Перейти к содержимому
Теория · Переменные и типы · урок 6 из 10

Нулевые значения

Что лежит в новой коробке, в которую ещё ничего не положили? В Go ответ всегда известен заранее. Каждая новая коробка приходит с содержимым по умолчанию, и оно зависит от её формы: в коробке для чисел лежит 0, в коробке для текста — пустая строка.

Переменную можно объявить через var без начального значения. В некоторых языках чтение такой переменной — ошибка или случайное число из памяти. В Go её значение всегда определено:

GO
package main

import "fmt"

func main() {
    var n int
    var f float64
    var s string
    var ok bool
    fmt.Println(n, f, s, ok) // 0 0  false
}

Каждая переменная, объявленная без значения, получает нулевое значение своего типа. Поэтому в Go нет ошибки «переменная не инициализирована»: читать переменную можно сразу после объявления.

Давайте разберём вывод 0 0 false по частям:

  1. Первый 0 — значение n.
  2. Второй 0 — значение f: нулевое значение float64 выводится без точки.
  3. Два пробела подряд — это пустая строка s: fmt.Println поставил пробел до неё и после неё.
  4. false — нулевое значение ok.

Значения по типам

ТипНулевое значение
int, float640
string"", пустая строка
boolfalse

У некоторых типов Go нулевое значение называется nil и означает «ничего». К string это не относится: строка никогда не бывает nil, а пустая строка записывается как "".

Здесь картинка с коробкой неточна. Пустая коробка в жизни — это «ничего». А новая переменная в Go не пуста: в ней лежит настоящее значение, например 0, и с ним можно считать, сравнивать и печатать.

Где появляется нулевое значение

Нулевое значение получает переменная, объявленная через var без значения:

  • короткое объявление без значения не бывает: справа от := всегда стоит значение;
  • поэтому переменную с нулевым значением объявляют только через var;
  • переменная, объявленная через var без значения вне функций, над func main, тоже получает нулевое значение.

Нулевое значение как начало

Нулевое значение удобно как начальное. Счётчик или сумму объявляют через var и сразу начинают прибавлять. Запись var total int = 0 говорит то же самое, только длиннее:

GO
var total int
total = total + 5
total = total + 7
fmt.Println(total) // 12

Давайте пройдём пример по строкам:

  1. var total int — total начинает с 0.
  2. total = total + 5 — теперь в total лежит 5.
  3. total = total + 7 — теперь 12.
  4. fmt.Println(total) печатает 12.

Вывод через Printf

Пустую строку в выводе Println не видно. fmt.Printf с подходящими знаками формата показывает каждое значение явно:

GO
var n int
var s string
var ok bool
fmt.Printf("%q %d %t\n", s, n, ok) // "" 0 false

Каждый знак формата печатает значения своего типа:

  • %q — строку в двойных кавычках, поэтому пустая строка видна как "", а строка из одного пробела — как " ";
  • %d — целое число;
  • %t — true или false.

Если знак не подходит к типу аргумента, программа не останавливается. Для строки fmt.Printf("%d\n", s) печатает %!d(string=).

Нулевые значения — частый вопрос на собеседовании. Обычно показывают такую программу и спрашивают, что она напечатает. Ответ требует знать две вещи:

  • нулевое значение каждого типа;
  • как его выводит каждый знак формата.

Частая ошибка

Пустую строку сравнили с nil. Оператор == сравнивает два значения и даёт true или false:

GO
var s string
fmt.Println(s == nil) // ✗
TEXT
invalid operation: s == nil (mismatched types string and untyped nil)

Значение типа string не может быть nil, и компилятор отвергает такое сравнение. Чтобы проверить, пуста ли строка, сравните её с "": s == "".

Главное

  • Переменная, объявленная через var без значения, получает нулевое значение своего типа и сразу готова к чтению.
  • Нулевое значение чисел — 0, строки — "", bool — false; строка никогда не бывает nil.
  • %d печатает целое, %q — строку в кавычках, %t — true или false, поэтому пустая строка видна как "".

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом