Изучай программирование в играх

₊⊹

ФУНКЦИИ

func — строительный блок любой Go-программы

Go Средний

[ ОБЪЯВЛЕНИЕ ФУНКЦИИ ]

Функция в Go объявляется ключевым словом func. Синтаксис: func имя(параметры) тип_возврата { тело }. Если функция ничего не возвращает, тип возврата не указывается.

GO
func greet(name string) string {
    return "Привет, " + name + "!"
}

func main() {
    msg := greet("Gopher")
    fmt.Println(msg)  // Привет, Gopher!
}
₊⊹
Тип после имени параметра:
В Go тип параметра пишется ПОСЛЕ имени: name string, а не string name. Это читается как "переменная name типа string".

[ НЕСКОЛЬКО ПАРАМЕТРОВ И ВОЗВРАТОВ ]

Главная особенность Go: функция может вернуть несколько значений. Это используется повсеместно — принято возвращать пару (результат, ошибка).

GO
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("деление на ноль")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 3)
    if err != nil {
        fmt.Println("Ошибка:", err)
        return
    }
    fmt.Printf("Результат: %.2f\n", result)  // 3.33
}
₊⊹
nil — нулевое значение для ошибок
nil — нулевое значение для указателей, интерфейсов, ошибок. Если err == nil, значит ошибки нет и операция прошла успешно. Это идиоматический Go.

[ ИМЕНОВАННЫЕ ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ ]

Возвращаемым значениям можно дать имена прямо в сигнатуре функции. Тогда return без аргументов вернёт их текущие значения — это называется "голый return".

GO
func minMax(numbers []int) (min, max int) {
    min, max = numbers[0], numbers[0]
    for _, n := range numbers {
        if n < min { min = n }
        if n > max { max = n }
    }
    return  // голый return — возвращает min и max
}

func main() {
    min, max := minMax([]int{3, 1, 7, 2, 9})
    fmt.Printf("Мин: %d, Макс: %d\n", min, max)
    // Мин: 1, Макс: 9
}

[ DEFER — ОТЛОЖЕННЫЙ ВЫЗОВ ]

defer откладывает вызов функции до момента, когда текущая функция завершится. Отложенные вызовы выполняются даже при возникновении ошибки. Несколько defer выполняются в порядке стека (последний добавленный — первый выполненный).

GO
func processFile() {
    fmt.Println("Открываем файл")
    defer fmt.Println("Закрываем файл")  // выполнится последним

    fmt.Println("Обрабатываем данные")
    fmt.Println("Сохраняем результат")
}
// Вывод:
// Открываем файл
// Обрабатываем данные
// Сохраняем результат
// Закрываем файл
₊⊹
defer — одна из самых элегантных идей Go
Ты объявляешь очистку рядом с созданием ресурса, а не в конце функции. Это делает код понятнее: открытие и закрытие файла находятся рядом, а не разделены сотнями строк.

[ ПОПРОБУЙ САМ ]

₊⊹ ЗАДАНИЕ

Напиши функцию pow(base, exp int) int, которая возвращает base в степени exp.
Используй цикл for внутри функции.
Вызови её с разными аргументами и выведи результаты.

[ ПОКАЗАТЬ РЕШЕНИЕ ]
package main

import "fmt"

func pow(base, exp int) int {
    result := 1
    for i := 0; i < exp; i++ {
        result *= base
    }
    return result
}

func main() {
    fmt.Println(pow(2, 10)) // 1024
    fmt.Println(pow(3, 4))  // 81
    fmt.Println(pow(5, 3))  // 125
}
◄ ЦИКЛЫ К ТЕОРИИ ►