Библиотека задач по Go | тесты, код, задания
5.97K subscribers
484 photos
3 videos
227 links
Задачи и тесты по Go для тренировки и обучения.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/ab1d67c2

Для обратной связи: @proglibrary_feeedback_bot

Наши каналы: https://yangx.top/proglibrary/9197
加入频道
💡Как тривиально проверить значения интерфейса на nil?

В Go новички часто сталкиваются с проблемой интерфейсных переменных, которым присваивается nil указатель. В таком случае, хотя значение в интерфейсе является nil, сама переменная интерфейса не равна nil.

Пример: создаем переменную x как указатель на int, который по умолчанию nil, и переменную y как пустой интерфейс, который тоже nil по умолчанию. После присваивания x переменной y, интерфейс y уже не является nil, хотя x все еще nil.


var x *int
var y any
y = x


📌 Что вернет y == nil?

Вернет false. Это потому, что интерфейс не просто представляет значение, которое ему присвоено, а действует как контейнер для этого значения.

Для проверки, является ли значение в интерфейсе nil, нужно использовать утверждение типа. Например, для проверки y на nil, используем:


y.(*int) == nil


Это показывает, что интерфейс y не nil, но содержащееся в нем значение — nil. Полный пример здесь.

#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
💡Стек или куча?

🤔 Живет ли переменная на стеке вызовов, или она динамически выделена в куче?

В большинстве случаев вам не стоит беспокоиться об этом. Go собирает мусор и автоматически очищает неиспользуемые переменные.

Однако сборка мусора имеет свою цену, поэтому чем меньше выделений делает ваш код, тем быстрее он может работать.

📌 Как узнать, выделяется ли переменная в куче?

Некоторые операции по умолчанию вызывают выделение памяти в куче и поэтому легко обнаруживаются и исправляются. Вот несколько примеров:

🔸Строковые переменные неизменяемы. Конкатенация двух строк приводит к новой аллокации и сборке мусора. В качестве альтернативы можно использовать strings.Builder.
🔸Срезы, которые растут за пределы своей емкости, реаллоцируются. Решение: предварительно выделить срез с помощью make().
🔸Когда функция создает локальную переменную и возвращает указатель на эту переменную, переменная должна быть выделена в куче.

📌 Однако есть ситуации, когда выделения в куче неочевидны. Подумайте об указателях, скрытых внутри других типов данных, таких как срезы или мапы. Или рассмотрите массивы. Если массив слишком большой, чтобы жить на стеке, он выделяется в куче.

📌 Как найти эти случаи выделения в куче?

Запустите или скомпилируйте свой код с флагом сборки мусора "-m", и команда Go выведет заметку каждый раз, когда переменная перемещается или уходит со стека в кучу:

go run -gcflags "-m" 
или
go tools compile -m


#tip
💡 io.TeeReader можно использовать для копирования содержимого одного ридера в новый. Этот метод полезен, когда тело HTTP-запроса нужно прочитать дважды.

👉 Юзкейс: логирование входящих запросов с помощью middleware перед обработкой запросов.

#tip by Golangbot
Флаг -cpu можно использовать при запуске тестов Go, чтобы указать список значений GOMAXPROCS, с использованием которых необходимо запустить тесты. Например,
go test -cpu=4,5 


запустит тесты 2 раза. Тесты сначала будут запущены с четырьмя процессорами, а затем второй раз — с пятью.

#tip