Константы (const) в Go вычисляются на этапе компиляции и могут иметь неявный тип. iota — это специальный идентификатор, который используется для генерации последовательных значений при объявлении константных блоков. iota увеличивается на единицу внутри блока при каждой новой константе.
Присваивание без указания типа приводит к тому, что константа может получить не тот тип, который ожидает разработчик, особенно если она участвует в арифметике или логических операциях. Это чревато неявными преобразованиями и ошибками компиляции.
Пример:
type Level int const ( Low Level = iota // Low: Level == 0 Medium // Medium: Level == 1 High // High: Level == 2 ) // А если не указать тип: const ( Foo = iota // Foo: int == 0 Bar // Bar: int == 1 )
Может ли значение константы с использованием iota быть "типизировано" и каким типом оно будет, если тип не задан явно?
Ответ: Если тип не указан явно, константа становится безтиповой и получает тип, выведенный из контекста использования (например, int, если используется в арифметике). Это может привести к проблемам при использовании типов-алиасов или при необходимости строгой типизации.
Пример:
type Status uint8 const ( Ready Status = iota+1 // Ok // если бы объявили просто const Ready = iota+1 — тип был бы int, не Status )
История
При серилизации статуса через json, разработчик объявил const с помощью iota без явного типа. Результат — сериализация выдаёт int, а не человекочитаемую строку, из-за чего фронтенд начал неправильно интерпретировать пришедшее значение.
История
В проекте был введён тип State (type State int), но константы остались объявлены без типа. Это привело к тому, что интерфейсы не могли принимать значения типа State, и возникали неприятные баги, связанные с несовпадением типов при сравнении констант и переменных.
История
Инженер добавил новое значение enum через iota, не указав тип. В результате компилятор разрешал сравнивать константу с любой другой переменной типа int, что привело к ошибкам ветвления бизнес-логики на production.