День 03 · дополнительные материалы

День 03 — глубже

Всё здесь необязательно. Материалы на английском помечены. Первые три раздела — продолжение страниц дня: то, что в них не влезло.


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

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

Код для чтения · разбираем, набирать не нужно
	var a int
	var b float64
	var c string
	var d bool
	fmt.Println(a, b, c, d)
Вывод · это печатает программа, набирать не нужно
0 0  false

Между 0 и false два пробела: там напечатана пустая строка "", а Println поставил пробелы до неё и после. Нулевые значения ещё понадобятся в дне 06, когда появятся условия: переменная без значения там не «пустая», а вполне определённая.

Почему int(3.99) не компилируется, а int(4.0) — да

Число, записанное прямо в коде, — константа без типа. Компилятор знает её значение заранее и подгоняет под тип соседа: если при этом ничего не теряется (4.0 → 4, var w float64 = 3 → 3.0), он молча соглашается; если теряется дробь (int(3.99), x * 2.5 при целом x, var qty int = 12.5), отказывается собирать программу. Значение переменной известно только при работе, поэтому там компилятор ничего не решает: int(w) — ваше явное разрешение отбросить дробь, а float64(x) — явное разрешение расширить целое.

Из той же логики ещё три сообщения дня — они попадаются, когда тип переменной и тип значения не сходятся:

Что видите Что это значит Что делать
cannot use weight * 4 (value of type float64) as int value in variable declaration дробный результат кладёте в переменную int переменная float64 или int(weight * 4)
cannot use count (variable of type int) as float64 value in variable declaration целую переменную кладёте в дробную float64(count)
x / 2.0 печатает целое 2.0 подогнано под int соседа float64(x) / 2

Ещё три находки go vet

К двум сообщениям с четвёртой страницы — те, что встречаются чаще всего:

Код Что напечатает Что скажет go vet .
fmt.Printf("Итого: %d\n") Итого: %!d(MISSING) fmt.Printf format %d reads arg #1, but call has 0 args
fmt.Printf("Итого: %d руб. %02d коп.\n", 123) Итого: 123 руб. %!d(MISSING) коп. fmt.Printf format %02d reads arg #2, but call has 1 arg
fmt.Printf("Итого: %d\n", 5, 7) Итого: 5, на следующей строке %!(EXTRA int=7) fmt.Printf call needs 1 arg but has 2 args

Тур по Go: типы и константы (англ.)

Константы подробно (англ.)

Почему 0.1 + 0.2 не 0.3 (англ.)

Все глаголы Printf (англ.)

Мини-опыты в ~/gocourse/day03/scratch

✎ Наберите в файл scratch/main.go
	total := 5997
	pct := 7
	fmt.Println(total*pct/100, total/100*pct, pct/100*total)