Утверждение типа в if с затенением переменной — кандидат не видит нулевое значение

На собесе дают код с type assertion внутри if и просят сказать, что выведется. Легко ответить уверенно и неправильно: затенение переменной в блоке if не бросается в глаза.

Классическая ловушка: переменная объявлена во внешней области видимости через var data any = "not an int", а внутри if через := создаётся новая переменная с тем же именем, но другого типа.

var data any = "not an int"

if data, ok := data.(int); ok { fmt.Println(data) } else { fmt.Println(data) }

Утверждение data.(int) не проходит — исходное значение это строка. ok становится false, идём в else. Но data внутри этого if — уже новая переменная типа int, объявленная через :=, и она получила нулевое значение для int, то есть 0. Выведет 0, а не «not an int».

Следующий вопрос: «а если написать просто data = data.(int)?» Код скомпилируется, но упадёт: утверждение без второго значения при неудаче паникует — interface conversion: interface {} is string, not int. А с data, ok = data.(int) и заранее объявленным ok затенения нет: внешняя data перезапишется нулём, и после if в ней будет 0, а не строка.

Переменные из условия if видны и в else: := создаёт новую data, и обе ветки печатают именно её.

Тренажёр: 1900+ вопросов и задач, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки