День 03 · Типы и арифметика · страница 1 из 6

Типы значений

Сегодня программы начнут считать: сумму заказа, число коробок, среднюю цену. Для этого надо знать, какие бывают значения и что с ними можно делать, — за это в Go отвечает тип. Модуль дня — ~/gocourse/day03, черновик — папка scratch в нём.


Зачем значению тип

Ситуация. В дне 02 строка var stock int = "40" не компилировалась: в переменную для целых чисел нельзя положить текст, даже если в нём одни цифры. Тип отвечает на три вопроса: что можно положить в переменную, что с этим делать и как печатать. Сегодня — четыре типа, которых хватит на весь первый блок:

Тип Что хранит Примеры значений Что с ним делают
int целые числа 12, -3, 0 считают: + - * / %
float64 дробные числа 2.5, -0.75, 3.0 считают, деление дробное
string текст "Север", "12", "" склеивают, печатают
bool «да» или «нет» true, false пока только хранят и печатают
Код для чтения · разбираем, набирать не нужно
package main

import "fmt"

func main() {
	var qty int = 12
	var weight float64 = 2.5
	var name string = "Коробка"
	var inStock bool = true
	fmt.Println(qty, weight, name, inStock)
}

Что увидите.

Пример · только посмотреть, набирать не нужно
stagiaire@lab:~/gocourse/day03/scratch$ go run .
12 2.5 Коробка true

Как это читать. Дробный разделитель — точка: запятая разделяет аргументы. Текст — в двойных кавычках, true — без них: "true" уже строка. float64 — от floating point, «плавающая точка», 64 — бит памяти. У bool два значения, и сегодня он только хранится: сравнения и if — в день 06.


Попробуйте сейчас: четыре типа в черновике.

Цель: программа в scratch печатает значения четырёх типов.

  1. В черновике ~/gocourse/day03/scratch уже лежит заготовка main.go — замените её текст программой выше:
✎ Наберите в файл scratch/main.go
package main

import "fmt"

func main() {
	var qty int = 12
	var weight float64 = 2.5
	var name string = "Коробка"
	var inStock bool = true
	fmt.Println(qty, weight, name, inStock)
}
  1. Запустите:
▶ Выполните
cd ~/gocourse/day03/scratch
go run .

Должно получиться:

Вывод · это печатает программа, набирать не нужно
12 2.5 Коробка true

Готово, когда: напечаталось 12 2.5 Коробка true; запуск засчитан в пункте t_gorun.


Тип при :=

При записи x := значение тип не пишут — Go берёт его из значения справа:

Запись Тип переменной
qty := 12 int
weight := 2.5 float64
total := 3.0 float64 — точка делает число дробным, даже если после неё ноль
code := "12" string
paid := false bool

Тип задаётся один раз и больше не меняется: переменная, созданная целой, остаётся целой до конца программы.

Дальше показываем только строки из тела main — вставляйте их между { и } в scratch/main.go. С одним import "fmt" первая строка тела — шестая. Номера строк считаются от начала файла, включая пустые. В файлах заданий первой строкой часто стоит комментарий, и номера сдвигаются вниз.

Код для чтения · разбираем, набирать не нужно
	qty := 5
	qty = 2.5
	fmt.Println(qty)
Пример · только посмотреть, набирать не нужно
stagiaire@lab:~/gocourse/day03/scratch$ go run .
# day03/scratch
./main.go:7:8: cannot use 2.5 (untyped float constant) as int value in assignment (truncated)

Как это читать. Строка 7 — это qty = 2.5. 2.5 (untyped float constant) — «дробное число из кода, у которого пока нет типа»; Go пробует подогнать его под тип переменной, int, и (truncated) — «пришлось бы отрезать дробную часть». Молча терять часть числа Go не станет.

В обратную сторону можно — целое число без потерь становится дробным:

Код для чтения · разбираем, набирать не нужно
	var w float64 = 3
	x := 2.5 * 4
	fmt.Println(w, x, 30.0, 0.5)
Вывод · это печатает программа, набирать не нужно
3 10 30 0.5

Println печатает дробное без хвоста .0, поэтому по выводу 3 тип не угадать: как спросить его у программы — на четвёртой странице.


Что может пойти не так

Что видите Что это значит Что делать
cannot use 12.5 (untyped float constant) as int value in variable declaration (truncated) дробное число кладёте в переменную int при объявлении нужна дробь — тип float64, иначе целое число
cannot use 2.5 … as int value in assignment (truncated) то же при присваивании: переменная уже int, создана как qty := 5 создавать её дробной: qty := 5.0
cannot use "двенадцать" … as int value in assignment в целую переменную кладёте текст число — без кавычек
cannot use "true" … as bool value in variable declaration true в кавычках — это строка true без кавычек; 1 вместо true тоже не подойдёт

Попробуйте сейчас: сломайте типы тремя способами.

Цель: прочитать сообщения о несовпадении типов, сверить их с таблицей и записать одно в словарик.

  1. Вставьте в тело main в scratch/main.go три строки из примера выше:
✎ Наберите в файл scratch/main.go
	var w float64 = 3
	x := 2.5 * 4
	fmt.Println(w, x, 30.0, 0.5)
▶ Выполните
go run .

Должно получиться 3 10 30 0.5: целое стало дробным без ошибки.

  1. Замените их фрагментом с qty = 2.5:
✎ Наберите в файл scratch/main.go
	qty := 5
	qty = 2.5
	fmt.Println(qty)

Запустите go run . и сравните номер строки в сообщении с номером строки qty = 2.5 в VS Code.

  1. Верните программу из первого раздела и сломайте её двумя способами, каждый раз запуская и читая сообщение до конца: var qty int = 12.5, потом var inStock bool = "true". Оба сообщения есть в таблице выше — сверьте буква в букву.
  2. Сообщение про 12.5 запишите в ~/errors.md строкой «текст ошибки — что значило», как в день 01: разделитель — только тире.
  3. Верните программу в рабочий вид.

Готово, когда: номер строки совпал с VS Code, оба сообщения сверены с таблицей, в ~/errors.md новая строка с тире, а go run . снова печатает 12 2.5 Коробка true.


Дальше: арифметика целых чисел — course next