В Go типы видны рано. Это хорошо: компилятор сразу говорит, где вы смешали число, строку или результат функции не так, как ожидали. В этом уроке мы сделаем небольшой расчет заказа: цена, количество, скидка, итоговая сумма и текстовый статус. На нем разберем int, float64, string, bool, :=, var, return и функцию с несколькими возвращаемыми значениями
Что получится в конце
Мы напишем файл main.go, который выводит расчет:
Товар: Книга по Go
Количество: 3
Итог: 2550
Скидка применена: true
Код будет маленьким, но похожим на настоящую бизнес-логику: есть входные значения, функция расчета и проверяемый вывод
Подготовка проекта
Создайте папку:
mkdir go-types
cd go-types
go mod init example.com/go-types
Создайте main.go:
package main
import "fmt"
func main() {
productName := "Книга по Go"
price := 1000.0
quantity := 3
discountPercent := 15.0
total, hasDiscount := calculateTotal(price, quantity, discountPercent)
fmt.Println("Товар:", productName)
fmt.Println("Количество:", quantity)
fmt.Println("Итог:", total)
fmt.Println("Скидка применена:", hasDiscount)
}
func calculateTotal(price float64, quantity int, discountPercent float64) (float64, bool) {
subtotal := price * float64(quantity)
if discountPercent <= 0 {
return subtotal, false
}
discount := subtotal * discountPercent / 100
return subtotal - discount, true
}
Запустите:
go run .
Как Go понимает типы
Строка:
productName := "Книга по Go"
создает переменную типа string. Мы не написали тип руками, потому что Go видит строковое значение справа
Строка:
quantity := 3
создает int
А здесь:
price := 1000.0
получается число с плавающей точкой. Для денежных расчетов в реальных системах часто используют целые копейки или decimal-библиотеки, но для учебного примера float64 удобен: сразу видно, как работает преобразование типов
Почему нужно float64(quantity)
В функции есть строка:
subtotal := price * float64(quantity)
price имеет тип float64, а quantity имеет тип int. Go не умножает их автоматически. Нужно явно сказать: для этого расчета воспринимаем quantity как float64
Это одна из важных привычек Go: язык не пытается молча угадать, что вы имели в виду. Он просит сделать преобразование явным. В учебном коде это кажется лишней строгостью, но в денежных и сетевых задачах такое поведение полезно
var и короткое объявление
Внутри функции часто пишут:
name := "Go"
Это короткое объявление переменной. Оно удобно, когда значение сразу известно
Можно написать подробнее:
var name string
name = "Go"
Такой вариант нужен, когда переменную нужно объявить заранее, а значение появится позже
Еще один пример:
var attempts int
fmt.Println(attempts)
Если значение не задано, Go использует zero value. Для int это 0, для string пустая строка, для bool значение false
Функция с параметрами и return
Функция расчета:
func calculateTotal(price float64, quantity int, discountPercent float64) (float64, bool) {
subtotal := price * float64(quantity)
if discountPercent <= 0 {
return subtotal, false
}
discount := subtotal * discountPercent / 100
return subtotal - discount, true
}
После имени функции идут параметры: price, quantity, discountPercent. У каждого указан тип
После параметров написано:
(float64, bool)
Это значит, что функция возвращает два значения: итоговую сумму и признак, была ли применена скидка. В Go несколько возвращаемых значений встречаются постоянно. Особенно часто так возвращают результат и ошибку
Вызов выглядит так:
total, hasDiscount := calculateTotal(price, quantity, discountPercent)
Слева две переменные, потому что справа функция возвращает две вещи
Как добавить проверку минимальной суммы
Изменим задачу: скидка применяется только если сумма до скидки больше или равна 2000
func calculateTotal(price float64, quantity int, discountPercent float64) (float64, bool) {
subtotal := price * float64(quantity)
if discountPercent <= 0 || subtotal < 2000 {
return subtotal, false
}
discount := subtotal * discountPercent / 100
return subtotal - discount, true
}
Теперь код читает правило почти как текст: если скидка не задана или сумма меньше 2000, возвращаем исходную сумму и false
Тип bool и условия
bool хранит только true или false. Его удобно использовать для флагов:
isPaid := false
hasDiscount := true
В условиях Go не принимает числа вместо логического значения. Нельзя написать if quantity { ... }. Нужно явно сравнить:
if quantity > 0 {
fmt.Println("Можно оформить заказ")
}
Такой стиль делает условия менее двусмысленными
Частые ошибки
*invalid operation: price quantity.** Скорее всего, вы умножаете float64 и int. Добавьте явное преобразование: float64(quantity)
declared and not used. В Go нельзя объявить переменную и не использовать ее. Либо используйте переменную, либо удалите
not enough return values. Функция объявлена как возвращающая два значения, но в одной из веток вы вернули только одно. Проверьте все return
no new variables on left side of :=. Вы пытаетесь использовать :=, хотя переменная уже объявлена. Для повторного присваивания используйте =
Что может быть еще интересно по этой теме
Когда писать тип явно? Если значение очевидно, := нормально. Если тип важен для чтения кода или значение появится позже, используйте var name type
Почему Go не преобразует числа сам? Чтобы не было скрытых потерь точности и странных ошибок. Явное преобразование показывает намерение
Можно ли возвращать больше двух значений? Можно, но не стоит превращать функцию в выдачу всего подряд. Если возвращаемых данных много, часто лучше собрать их в struct
Почему функция называется с маленькой буквы? В Go имя с маленькой буквы доступно только внутри пакета. Имя с большой буквы экспортируется наружу. Для учебного main это не важно, но правило полезно запомнить
Что открыть дальше
- Go с нуля: первый файл, go run и fmt.Println — если нужно повторить запуск проекта.
- Struct и методы в Go: первый объект без ООП-магии — следующий шаг после отдельных переменных.
- Interfaces в Go простыми словами — когда появится несколько типов с одинаковым поведением.
- Ошибки в Go: error, panic и recover без суеты — чтобы понять стандартный стиль
result, err.



