[ ОБЪЯВЛЕНИЕ ФУНКЦИИ ]
Функция в Go объявляется ключевым словом func. Синтаксис: func имя(параметры) тип_возврата { тело }. Если функция ничего не возвращает, тип возврата не указывается.
func greet(name string) string {
return "Привет, " + name + "!"
}
func main() {
msg := greet("Gopher")
fmt.Println(msg) // Привет, Gopher!
}
В Go тип параметра пишется ПОСЛЕ имени:
name string, а не string name. Это читается как "переменная name типа string".
[ НЕСКОЛЬКО ПАРАМЕТРОВ И ВОЗВРАТОВ ]
Главная особенность 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 — нулевое значение для указателей, интерфейсов, ошибок. Если err == nil, значит ошибки нет и операция прошла успешно. Это идиоматический Go.
[ ИМЕНОВАННЫЕ ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ ]
Возвращаемым значениям можно дать имена прямо в сигнатуре функции. Тогда return без аргументов вернёт их текущие значения — это называется "голый return".
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 выполняются в порядке стека (последний добавленный — первый выполненный).
func processFile() {
fmt.Println("Открываем файл")
defer fmt.Println("Закрываем файл") // выполнится последним
fmt.Println("Обрабатываем данные")
fmt.Println("Сохраняем результат")
}
// Вывод:
// Открываем файл
// Обрабатываем данные
// Сохраняем результат
// Закрываем файл
Ты объявляешь очистку рядом с созданием ресурса, а не в конце функции. Это делает код понятнее: открытие и закрытие файла находятся рядом, а не разделены сотнями строк.
[ ПОПРОБУЙ САМ ]
Напиши функцию 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
}