Shanraq.org Shanraq.org
Переменные и типы в Go: string, int, float64 и bool
IT

Go: с нуля до своего блога Урок 4 из 50

Переменные и типы в Go: string, int, float64 и bool

Четвёртый урок курса по Go. Что такое переменная и зачем языку типы: string, int, float64 и bool, объявление через := и var, нулевые значения и почему тип выбирается один раз. Разбираем ошибку declared and not used, которую вы увидите в первый же день, и правила именования.

Зачем это нужно

Ваш сервер отвечает всем одно и то же. Чтобы отвечать по-разному — имя читателя, заголовок статьи, число просмотров — программе надо где-то держать значения. Место для значения называется переменной.

И Go всегда спрашивает, какого рода это значение: текст, число, «да-нет». Это называется типом. На нём язык ловит целый класс ошибок ещё до того, как программа запустится.

Сразу целиком

Новая папка, go mod init sabaq03, файл main.go:

package main

import "fmt"

func main() {
	title := "Привет, мир!"
	views := 0
	rating := 4.5
	published := true

	views = views + 1

	fmt.Println(title)
	fmt.Println("Просмотров:", views)
	fmt.Println("Оценка:", rating)
	fmt.Println("Опубликовано:", published)
}

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

go run . печатает:

Привет, мир!
Просмотров: 1
Оценка: 4.5
Опубликовано: true

Четыре переменные — это уже почти карточка статьи в вашем будущем блоге.

Разбор

Переменная — это имя для значения

Коробка с подписью. views — это не число 0, а имя, за которым сейчас лежит 0. Через строчку там уже 1.

Образ. Подписанная коробка на полке. Надпись «просмотры» не меняется, а содержимое меняется когда угодно. Вы говорите «принеси просмотры», а не «принеси ноль».

:= объявляет и сразу кладёт значение

title := "Привет, мир!" читается как «заведи title и положи в него эту строку».

Тип мы нигде не написали. Go посмотрел, что справа, и понял сам — это называется выводом типа. Слева текст в кавычках, значит title — строка.

Образ. := — завести новую коробку и подписать её. = — положить вещь в коробку, которая уже подписана и стоит на полке. Подписывать дважды одну и ту же коробку незачем.

Знак := работает только при первом появлении имени. Дальше обычное =:

views = views + 1

Читайте это не как уравнение, а как приказ: возьми то, что лежит в views, прибавь единицу, положи обратно. В математике такая запись была бы неверной, в программировании это норма.

Четыре типа, которых пока хватит

  • string — текст: заголовок, имя, адрес. Пишется в двойных кавычках.
  • int — целое число: просмотры, количество комментариев.
  • float64 — число с дробной частью: оценка 4.5, рост, температура. Разделитель — точка, не запятая. Деньги так не хранят: float64 считает приблизительно, и копейки со временем разъезжаются. Для денег берут целое число самых мелких единиц — тиынов — или отдельный десятичный тип.
  • bool — только true или false: опубликовано или нет.

Имена этих встроенных типов пишутся с маленькой буквы. У типов, которые вы создадите сами, регистр первой буквы будет значить другое — видно ли имя за пределами пакета; до этого дойдём в уроке про структуры.

Образ. Тип — это форма коробки. В обувную не влезет холодильник, и это хорошо: несоответствие видно на складе, а не дома у покупателя.

var — когда значения ещё нет

Бывает, что переменная нужна, а чем её заполнить, вы узнаете позже:

var author string
var count int
var ok bool

Здесь тип пришлось назвать самому — выводить его не из чего. Go кладёт в такую переменную нулевое значение её типа: "" для строки, 0 для числа, false для bool.

Это важнее, чем кажется. В Go не бывает переменной «неизвестно с чем внутри»: она всегда чем-то заполнена. Целый класс ошибок, на котором спотыкаются в других языках, здесь просто не возникает.

Образ. Пустой стакан — это пустой стакан, а не «неизвестно что». Вы можете его взять, посмотреть на просвет и налить в него. В некоторых языках на этом месте стоит «неизвестно, есть ли вообще стакан», и об это спотыкаются.

const — то, что не меняется никогда

Бывает наоборот: значение известно заранее и меняться не должно. Предел длины заголовка, адрес сайта, названия состояний. Для такого есть const:

const maxTitle = 80
const site = "shanraq.org"

const (
	draft = iota
	review
	published
)

func main() {
	fmt.Println("предел заголовка:", maxTitle)
	fmt.Println("сайт:", site)
	fmt.Println("статусы:", draft, review, published)
}
предел заголовка: 80
сайт: shanraq.org
статусы: 0 1 2

Разница с переменной одна, и она жёсткая. Попробуйте изменить константу — программа не соберётся:

cannot assign to maxTitle (neither addressable nor a map index expression)

iota в скобках — счётчик, который начинается с нуля и растёт на единицу с каждой строкой. Он нужен, когда состояний несколько и важны не сами числа, а то, что они разные: draft, review, published вместо 0, 1, 2 в коде, где через месяц никто не вспомнит, что значила двойка.

Ещё одно правило: значение константы должно быть известно при сборке, а не при работе. Отсюда вторая ошибка, которую стоит увидеть заранее:

var author = "Даулет"

const site = author
author (variable of type string) is not constant

Переменную можно изменить, значит, её значение неизвестно до запуска — в константу оно не годится.

Образ. Печать в отличие от карандашной пометки. Пометку правят, печать — нет: её вырезали один раз, и дальше она везде одинаковая.

Правило простое: если значение вписано в код руками и меняться не должно, пишите const. Число 80, разбросанное по коду в четырёх местах, однажды поменяют в трёх.

Тип выбирается один раз и не меняется

views объявлен целым числом, и текст в него уже не положить:

views = "много"

Go откажется собирать программу и скажет примерно так:

cannot use "много" (untyped string constant) as int value in assignment

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

Ошибка, которую вы увидите сегодня

Объявите переменную и не используйте её — Go откажется собирать программу:

declared and not used: author

Почти любой другой язык промолчал бы. Go считает неиспользованную переменную мусором и не пускает его дальше.

Лечится двумя способами: используйте её или уберите. Раздражает ровно первую неделю, потом начинаете ценить.

Как называть переменные

Латиницей, без пробелов. Несколько слов пишут слитно, каждое следующее с большой буквы: articleTitle, viewsCount. Это называется camelCase, и так принято во всём Go.

Образ. Так подписывают папки в шкафу. Не «п1», а «Договоры аренды 2026» — чтобы через год открыть шкаф и найти с первого раза.

Имя должно говорить, что внутри. t вы через неделю не вспомните, title поймёте всегда.

Карта урока

Карта урока: четыре типа и то, что тип выбирается один раз

Скажите своими словами

Не подглядывая, ответьте вслух или на бумаге. Ответы — в конце урока.

  1. Чем := отличается от =?
  2. Вы написали var price float64 и ничего туда не положили. Что лежит в price?
  3. Почему Go отказывается собирать программу из-за неиспользованной переменной, хотя она никому не мешает?

Задание

Обязательное. Соберите карточку своей будущей статьи: четыре переменные со своими значениями и вывод их в терминал.

По желанию.

  • Попробуйте положить строку в переменную типа int и прочитайте сообщение целиком. Полезно увидеть эту ошибку намеренно, чтобы потом узнать её в лицо.
  • Объявите переменную и не используйте. Убедитесь, что Go не собрал программу.
  • Замените одно из объявлений с := на var с явным типом. Результат должен остаться тем же.

Если не получилось. go: cannot find main module или go.mod file not found — вы в папке без go.mod: выполните в ней go mod init sabaq03. undefined: fmt — нет строки import "fmt"; редактор дописывает её сам при сохранении, если вы поставили расширение Go. А declared and not used — это не поломка, а разговор из раздела выше.

Куда это встанет в блоге

Эти четыре переменные — поля вашей будущей статьи. В уроке про структуры мы соберём их в один тип Article, чтобы они ходили вместе, а в уроке про CRUD они поедут в базу и вернутся оттуда.

Ответы

Показать ответы
  1. := заводит новое имя и сразу даёт ему значение, а тип Go определяет сам. = кладёт значение в имя, которое уже существует. Повторить := с тем же именем можно — но только если слева есть хотя бы одно новое имя: тогда старое просто получает новое значение.
  2. Ноль. У каждого типа в Go есть нулевое значение: 0 у чисел, "" у строк, false у bool. Переменной «неизвестно с чем внутри», как в некоторых языках, здесь не бывает.
  3. Потому что неиспользованная переменная почти всегда след ошибки: вы что-то посчитали и забыли применить, или опечатались в имени ниже. Go предпочитает остановить вас сейчас, а не дать этому доехать до читателя.

Источники

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Проверить задание

Сначала решите и запустите в VS Code — редактор покажет ошибку на месте. Готовое решение вставьте сюда. Проверяет модель: она укажет на ошибку, но не даст готовый ответ.

Чтобы проверить, нужно войти. Войти

Комментарии (0)

Пока нет комментариев. Будьте первым.