Переменная — это имя для значения, которое лежит в памяти. В Go у каждой переменной есть тип, и он известен ещё до запуска программы: компилятор знает, что в age лежит целое число, а в name — строка. Благодаря этому многие ошибки ловятся при сборке, а не у пользователя.
В этой главе разберёмся, как объявлять переменные двумя способами (var и :=), какие есть базовые типы (int, float64, bool, string), что такое нулевые значения, как объявлять константы с iota и почему Go заставляет преобразовывать типы вручную.
Внутри функций чаще всего пишут ещё короче — через :=. Это объявление и присваивание одновременно, тип всегда выводится автоматически:
age := 30name := "Аня"active := true
Запись := работает только внутри функций. На верхнем уровне пакета (вне функций) используйте var. И ещё: := именно создаёт новую переменную. Если переменная уже есть и вы хотите просто поменять её значение — используйте обычное =:
x := 10 // создалиx = 20 // изменили
Соберём всё вместе и посмотрим на типы. Функция fmt.Printf с глаголом %T печатает тип значения, а %v — само значение:
package mainimport "fmt"func main() { var age = 30 price := 19.99 name := "Аня" active := true fmt.Printf("age=%v (%T)\n", age, age) fmt.Printf("price=%v (%T)\n", price, price) fmt.Printf("name=%v (%T)\n", name, name) fmt.Printf("active=%v (%T)\n", active, active)}
int — целые числа (-2, 0, 42). Это «число по умолчанию»: если вы пишете x := 7, получится int.
float64 — числа с дробной частью (3.14, -0.5, 19.99). Тип по умолчанию для дробей.
bool — логическое значение: только true или false.
string — текст в кодировке UTF-8 ("привет", ""). Строки в Go неизменяемы: вы не меняете строку, а создаёте новую.
Есть и другие числовые типы (int8, int64, uint, float32 и прочие) — они нужны, когда важен размер или знак. Пока достаточно знать, что они существуют; в обычном коде по умолчанию берут int и float64.
В Go не бывает «мусора» в неинициализированной переменной. Если вы объявили переменную, но не дали ей значения, она получает нулевое значение (zero value) своего типа — предсказуемое и безопасное:
у чисел (int, float64) это 0;
у bool — false;
у string — пустая строка "".
Это удобно: можно объявить переменную заранее и не бояться, что в ней окажется что-то случайное.
package mainimport "fmt"func main() { var n int var f float64 var b bool var s string fmt.Printf("int: %v\n", n) fmt.Printf("float: %v\n", f) fmt.Printf("bool: %v\n", b) fmt.Printf("string: %q\n", s)}
Вывод:
int: 0float: 0bool: falsestring: ""
Здесь %q берёт строку в кавычки — так сразу видно, что она пустая, а не «пропала».
Константа — это значение, которое известно на этапе компиляции и не может измениться во время работы программы. Объявляется через const:
const Pi = 3.14159const AppName = "MyApp"const MaxRetries = 3
Попытка присвоить константе новое значение — ошибка компиляции, программа просто не соберётся. Это страховка: имена вроде MaxRetries не должны меняться по ходу дела.
Часто нужно перечисление — набор связанных целых констант (дни недели, состояния, уровни). Чтобы не писать 0, 1, 2, 3 руками, в Go есть iota. Внутри блока constiota начинается с 0 и увеличивается на единицу с каждой следующей строкой:
Обратите внимание: значение = iota мы написали только в первой строке, а дальше Go повторяет эту же формулу для каждой константы — поэтому числа сами растут. Так из iota получается аккуратная нумерация без ручного счёта.
А вот это место часто удивляет новичков. В Go нет неявного преобразования между числовыми типами. Нельзя просто сложить int и float64 — компилятор откажется, даже если математически всё «понятно». Преобразование всегда пишется явно: T(value).
Зачем так строго? Чтобы вы сами решали, что делать с потерей точности. Превратить float64 в int — значит отбросить дробную часть, и Go хочет, чтобы это было ваше осознанное решение, а не случайность.
package mainimport "fmt"func main() { count := 3 // int price := 19.99 // float64 // count * price — ошибка: разные типы. // Приводим count к float64 явно: total := float64(count) * price fmt.Printf("total = %.2f\n", total) // Обратно: float64 -> int отбрасывает дробь (не округляет!) whole := int(price) fmt.Printf("whole = %d\n", whole)}
Вывод:
total = 59.97whole = 19
Запомните два момента: int(19.99) даёт 19, а не 20 — дробь именно отбрасывается, округления не происходит. И преобразование T(value) нужно применить к одному из операндов, чтобы их типы совпали.
:= вне функции. Короткое объявление работает только внутри функций. На уровне пакета пишите var.
:= для уже существующей переменной.:= создаёт новую переменную. Чтобы изменить имеющуюся, используйте =. Повторный := в той же области видимости — ошибка «no new variables on left side».
Неиспользуемая переменная. Go считает объявленную, но ни разу не использованную локальную переменную ошибкой компиляции. Это не придирка, а защита от опечаток. Если переменная пока не нужна — удалите её или используйте.
Сложение int и float64 напрямую. Так нельзя — преобразуйте один из операндов явно: float64(count) * price.
Теперь у вас есть переменные и типы — материал, на котором строится почти всё остальное. Дальше посмотрим, как из них собирать логику: условия и циклы (if, for, switch), а затем — как упаковывать код в функции.