Forwarded from Библиотека Go-разработчика | Golang
В Go новички часто сталкиваются с проблемой интерфейсных переменных, которым присваивае
тся
nil указатель. В таком случае, хотя значение в интерфейсе является
nil, сама переменная интерфейса не равна
nil.Пример: создаем перемен
н
ую x как указатель на
int, который по умолчанию
nil, и переменн
ую y как пустой интерфейс, который тоже
nil по умолчанию. После присваиван
ия x переменн
ой y, интерфе
йс y уже не является
nil, хо
тя x все еще
nil.
var x *int
var y any
y = x
📌 Что верне
т y == n
il? Верне
т fal
se. Это потому, что интерфейс не просто представляет значение, которое ему присвоено, а действует как контейнер для этого значения.Для проверки, является ли значение в интерфейс
е n
il, нужно использовать утверждение типа. Например, для проверки
y на n
il, используем:
y.(*int) == nil
Это показывает, что интерфейс
y
не nil
, но содержащееся в нем значение — nil
. Полный пример здесь.#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
go.dev
Go Playground - The Go Programming Language
👍7🤔4❤1🔥1
Forwarded from Библиотека Go-разработчика | Golang
💡Стек или куча?
🤔 Живет ли переменная на стеке вызовов, или она динамически выделена в куче?
В большинстве случаев вам не стоит беспокоиться об этом. Go собирает мусор и автоматически очищает неиспользуемые переменные.
Однако сборка мусора имеет свою цену, поэтому чем меньше выделений делает ваш код, тем быстрее он может работать.
📌 Как узнать, выделяется ли переменная в куче?
Некоторые операции по умолчанию вызывают выделение памяти в куче и поэтому легко обнаруживаются и исправляются. Вот несколько примеров:
🔸Строковые переменные неизменяемы. Конкатенация двух строк приводит к новой аллокации и сборке мусора. В качестве альтернативы можно использовать
🔸Срезы, которые растут за пределы своей емкости, реаллоцируются. Решение: предварительно выделить срез с помощью
🔸Когда функция создает локальную переменную и возвращает указатель на эту переменную, переменная должна быть выделена в куче.
📌 Однако есть ситуации, когда выделения в куче неочевидны. Подумайте об указателях, скрытых внутри других типов данных, таких как срезы или мапы. Или рассмотрите массивы. Если массив слишком большой, чтобы жить на стеке, он выделяется в куче.
📌 Как найти эти случаи выделения в куче?
Запустите или скомпилируйте свой код с флагом сборки мусора "
#tip
🤔 Живет ли переменная на стеке вызовов, или она динамически выделена в куче?
В большинстве случаев вам не стоит беспокоиться об этом. Go собирает мусор и автоматически очищает неиспользуемые переменные.
Однако сборка мусора имеет свою цену, поэтому чем меньше выделений делает ваш код, тем быстрее он может работать.
📌 Как узнать, выделяется ли переменная в куче?
Некоторые операции по умолчанию вызывают выделение памяти в куче и поэтому легко обнаруживаются и исправляются. Вот несколько примеров:
🔸Строковые переменные неизменяемы. Конкатенация двух строк приводит к новой аллокации и сборке мусора. В качестве альтернативы можно использовать
strings.Builde
r.🔸Срезы, которые растут за пределы своей емкости, реаллоцируются. Решение: предварительно выделить срез с помощью
make(
)
.🔸Когда функция создает локальную переменную и возвращает указатель на эту переменную, переменная должна быть выделена в куче.
📌 Однако есть ситуации, когда выделения в куче неочевидны. Подумайте об указателях, скрытых внутри других типов данных, таких как срезы или мапы. Или рассмотрите массивы. Если массив слишком большой, чтобы жить на стеке, он выделяется в куче.
📌 Как найти эти случаи выделения в куче?
Запустите или скомпилируйте свой код с флагом сборки мусора "
-
m", и команда Go выведет заметку каждый раз, когда переменная перемещается или уходит со стека в кучу:go run -gcflags "-m"
или
go tools compile -m
#tip
👍6❤1
Forwarded from Библиотека Go-разработчика | Golang
return early, return often
✅ Вместо глубоко вложенного кода, Go призывает разработчиков обрабатывать условия (особенно ошибки) и возвращать управление как можно скорее.
✅ Это делает код более читабельным и простым в сопровождении.
#go #tip by Matt Boyle
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🥱3
Forwarded from Библиотека Go-разработчика | Golang
🔗 pkg.go.dev
Здесь вы можете найдете пакеты по различным критериям и получите информацию о версии, лицензии и многом другом.
🔗 GitHub
Вводите в поисковую строку
language:go
+ свой запрос и анализируете результаты.🔗 Awesome Go
Один из самых старых и самых поддерживаемых кураторских списков по Go.
🔗 Libhunt.com
Коллекция Go-проектов, отфильтрованных по количеству упоминаний, звезд или другим критериям.
🔗 go-recipes
Тщательно подобранный список полезных Go-инструментов, разделенных на категориям.
#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
pkg.go.dev
Go Packages - Go Packages
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
🔥7❤3⚡2👍2
Forwarded from Библиотека Go-разработчика | Golang
context.Context
?HTTP-обработчики могут использовать контекст для управления тайм-аутами запросов или отменой в рамках запроса. Тип
Context
также позволяет передавать значения (например, идентификатор пользователя, связанный с запросом) другим функциям.❓Следует ли использовать этот механизм для передачи информации по цепочке вызовов запроса? Или лучше использовать обычную структуру?
Вот две причины, по которым использование
Context
для передачи значений может быть плохой идеей:Значения в
Context
представляют собой пары ключ/значение, где ключ и значение являются пустыми интерфейсами (т. е. any
). Другими словами, значения в контексте — это как мешок со всем подряд. Компилятор не может помочь вам отловить ошибки типов или даже проверить, есть ли информация. Удачи в устранении неполадок 😉Если вы видите функцию, принимающую параметр
Context
, вы не можете сказать, что внутри. Если вы видите функцию, которая принимает параметр структуры, вы можете ясно видеть, что данные передаются, и что это за данные.❓Но разве
doSomething(ctx)
не выглядит намного чище, чем doSomething(ctx, someStruct)
?Чистый код сам по себе не является целью. Код не чист только потому, что он короткий. Код чистый, если читатель может ясно видеть, что он делает.
❓Так
context.WithValue()
следует избегать?Значения в контексте могут быть полезны, если они не критичны для бизнес-логики приложения. Например, совершенно нормально передавать идентификаторы запросов для логирования или измерения метрик. Читатель все равно сможет понять логику кода, и если что-то пойдет не так с этим идентификатором, это повлияет только на логирование или метрики приложения, но не на результат запроса.
Context
.#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1
Forwarded from Библиотека Go-разработчика | Golang
В Go новички часто сталкиваются с проблемой интерфейсных переменных, которым присваивае
тся
nil указатель. В таком случае, хотя значение в интерфейсе является
nil, сама переменная интерфейса не равна
nil.Пример: создаем перемен
н
ую x как указатель на
int, который по умолчанию
nil, и переменн
ую y как пустой интерфейс, который тоже
nil по умолчанию. После присваиван
ия x переменн
ой y, интерфе
йс y уже не является
nil, хо
тя x все еще
nil.
var x *int
var y any
y = x
📌 Что верне
т y == n
il? Верне
т fal
se. Это потому, что интерфейс не просто представляет значение, которое ему присвоено, а действует как контейнер для этого значения.Для проверки, является ли значение в интерфейс
е n
il, нужно использовать утверждение типа. Например, для проверки
y на n
il, используем:
y.(*int) == nil
Это показывает, что интерфейс
y
не nil
, но содержащееся в нем значение — nil
. Полный пример здесь.#tip
Please open Telegram to view this post
VIEW IN TELEGRAM
go.dev
Go Playground - The Go Programming Language
👍10
Forwarded from Библиотека Go-разработчика | Golang
💡
👉 Юзкейс: логирование входящих запросов с помощью middleware перед обработкой запросов.
#tip by Golangbot
io.TeeReader
можно использовать для копирования содержимого одного ридера в новый. Этот метод полезен, когда тело HTTP-запроса нужно прочитать дважды.👉 Юзкейс: логирование входящих запросов с помощью middleware перед обработкой запросов.
#tip by Golangbot
🔥17
Forwarded from Библиотека Go-разработчика | Golang
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍5
Forwarded from Библиотека Go-разработчика | Golang
💡 Если у вас запущено множество локальных серверов, и вам надоело обращаться к ним как
Предположим, у вас есть локальный сервер на порту 9000. После установки Caddy, выполните команду:
и откройте https://myserver.localhost. Вы увидите, что сервер на
А если вы хотите проксировать больше серверов таким образом, создайте файл с именем
#tip
localhost:8081
, localhost:9000
и т. д., посмотрите в сторону Caddy. Он сделает настройку «доменов» для локальных серверов проще простого.Предположим, у вас есть локальный сервер на порту 9000. После установки Caddy, выполните команду:
caddy reverse-proxy --from myserver.localhost --to :9000
и откройте https://myserver.localhost. Вы увидите, что сервер на
localhost:9000
отвечает. Caddy даже предоставляет локальные TLS-сертификаты. А если вы хотите проксировать больше серверов таким образом, создайте файл с именем
Caddyfile
и введите конфигурацию хоста следующим образом:
myapp.localhost {
reverse-proxy :9000
}
myhugoblog.localhost {
reverse-proxy :1313
}
#tip
🔥22👍2
Forwarded from Библиотека Go-разработчика | Golang
Флаг
запустит тесты 2 раза. Тесты сначала будут запущены с четырьмя процессорами, а затем второй раз — с пятью.
#tip
-cpu
можно использовать при запуске тестов Go, чтобы указать список значений GOMAXPROCS
, с использованием которых необходимо запустить тесты. Например,go test -cpu=4,5
запустит тесты 2 раза. Тесты сначала будут запущены с четырьмя процессорами, а затем второй раз — с пятью.
#tip
👍13