Тут буду собирать разные неочевидные особенности языка, которые нужно запомнить и стоит применять в своих программах.
for – range
по указателю
С циклом for — range
связан важный момент — операнд range
копируется во временную переменную, которая уже используется для обхода.
Это также может замедлить выполнение программы для массивов, поэтому следует использовать взятие указателя, чтобы не простаивать:
Источник – Массивы в Go.
Возвращаемые функцией значения могут иметь имя
Список возвращаемых значений имеет тот же синтаксис, что и список параметров. Например, можно написать коротко:
Обратите внимание, что здесь возвращаемые значения имеют имена. В теле функции они могут использоваться как обычные переменные. При входе в функцию они будут инициализированы значениями по умолчанию для данного типа.
Если функция содержит именованные возвращаемые значения, то необязательно указывать список возвращаемых значений оператором return
. В таком случае будут возвращены значения переменных, которые они имеют к этому моменту.
Вот функция, которая находит индекс буквы в строке и возвращает вторым аргументом false
, если буква не найдена:
Источник – Функции
Функция init()
В базовом синтаксисе языка также описана вот эта функция:
В пакете и даже в одном файле можно декларировать несколько таких функций. Они будут вызваны один раз при инициализации пакета, после присвоения глобальных переменных, в том порядке, в котором они предоставлены компилятору (встречаются в исходном тексте). Прямой вызов функции init()
в коде программы не предусмотрен.
Служат эти функции для создания окружения, необходимого пакету для корректной работы.
Вот простой пример:
Источник – Функции
Порядок импорта
Рассмотрим подробнее, как выполняется импорт пакетов.
- При компиляции программы компилятор начинает с пакета
main
. Если вmain
есть импорты каких-либо пакетов, то он переходит к ним и компилирует их, до тех пор пока не скомпилируются все необходимые пакеты для сборки программы. - Затем компилятор компилирует пакет
main
и собирает основное приложение, а далее в процессе выполнения программы произойдёт следующее: 1. В том порядке, в котором пакеты были проимпортированы, будут инициализироваться переменные пакета. 2. После будут выполнены функцииinit()
внутри каждого пакета. Функцийinit()
может быть несколько, и они выполнятся в том порядке, в котором были объявлены. 3. И после их выполнения наступит очередь функцииmain
.
Таким образом, часть кода по инициализации может быть выполнена ещё до запуска основной программы.
Источник – Пакеты и импорты в Go
Пустой импорт
Если импортировать пакет, но не использовать его внутри файла, компилятор выдаст ошибку. Однако бывают ситуации, когда нужно, чтобы импортируемый пакет вызвал функцию init
для инициализации данных. В этом случае указывается знак подчёркивания _
вместо альтернативного имени импортируемого пакета.
В качестве примера можно привести очень удобный пакет embed
из стандартной библиотеки. Он позволяет инициировать значения строковых переменных содержимыми файла.
В первом случае можем получить пустой импорт, когда пакет не используется напрямую, не вызываются функции из него, а импортируются только аннотации в комментариях.
Второй случай — применение в процессе разработки. Go запрещает компилировать код, в котором есть неиспользованные импорты, но иногда при отладке импорт нужно оставлять. Тогда он может быть помечен как пустой.
Источник – Пакеты и импорты в Go
📂 Go | Последнее изменение: 27.08.2024 23:49