Переменные, типы и функции в Go

В 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 это не важно, но правило полезно запомнить

Что открыть дальше

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x