Циклы и функции

Объявление функций, параметры, несколько возвращаемых значений и область видимости

Содержание курса

Несколько возвращаемых значений и пустой идентификатор _

Go позволяет функции возвращать сразу несколько значений. Типы перечисляются в скобках после списка параметров:

func divide(a, b float64) (float64, bool) {
    if b == 0 {
        return 0, false
    }
    return a / b, true
}

Функция возвращает два значения: частное и признак того, что деление прошло успешно. Если делитель равен нулю — возвращаем 0 и false, не пытаясь делить. Никаких исключений — второе значение просто сигнализирует о проблеме.

При вызове оба значения принимаются через множественное присваивание:

result, ok := divide(10, 3)
if ok {
    fmt.Println(result) // 3.3333333333333335
} else {
    fmt.Println("деление на ноль")
}

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

Если результаты функции нужно принять в переменные, число позиций слева от := должно совпадать с числом возвращаемых значений. Когда одно из значений не нужно, его позицию занимает _ — пустой идентификатор:

result, _ := divide(10, 3) // принимаем только частное
fmt.Println(result)

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

Обратная ситуация — нужен только признак успеха:

_, ok := divide(10, 0)
if !ok {
    fmt.Println("деление невозможно")
}

Есть и ещё один вариант: если результаты функции вообще не нужны, вызов можно написать как самостоятельную инструкцию — тогда все возвращаемые значения молча отбрасываются без какого-либо _:

divide(10, 3) // результат никуда не идёт — допустимо

Правило про _ касается именно присваивания: если вы пишете x, y := f(), позиций слева должно быть ровно столько, сколько значений возвращает f. Пропустить позицию нельзя — только заменить её на _.