Функции в Go отличаются от PHP тем, что:
- объявляются с помощью ключевого слова
func
- необходимо указывать тип каждого аргумента функции и возвращаемого значения
- функция может иметь несколько возвращаемых значений
Простой пример:
// Функция с двумя параметрами int и одним возвращаемым значением типа int
func add(x int, y int) int {
return x + y
}
Если несколько аргументов имеют одинаковый тип, то можно перечислить их через запятую:
// Краткий аналог предыдущего примера
func add(x, y int) int {
return x + y
}
Возврат нескольких значений:
// Нет аргументов, но два возвращаемых параметра
func minMax() (int, int) {
return 5, 6
}
// Так можно получить несколько значений
min, max := minMax()
То обстоятельство, что функция может возвращать несколько значений используется для обработки ошибок:
value, err := readSomeValue()
// 1. Что такое nil смотри в следующей главе
// 2. Обратите внимание на отсутствие скобочек вокруг условия в if
if err != nil {
// Обрабатываем ошибку
}
// Обрабатываем данные
Можно указывать пустой return, возвращая при этом данные (naked return). Для этого переменные должны быть объявлены сигнатуре функции.
// Можно дать имена возвращаемым переменным, так можно использовать return без
// перечисления переменных
func minMax() (min int, max int) {
max = 5 // Используется =, а не := так как переменная уже объявлена
return
}
min, max := minMax() // Какое значение будет у min?
Если одно из возвращаемых значений нам не нужно, то следует
использовать пустую переменную _
_, max := minMax()
Ключевое слово defer
одна из особенностей языка, аналогов которой нет в PHP.
defer
позволяет отложить исполнение кода, до конца выполнения текущей функции.
Например, в следующем примере closeFile будет вызвана в любом случае в конце функции:
func foo() bool {
file := openFile()
defer closeFile()
hasError := checkFile(file)
if hasError {
return false
}
// Продолжаем обработку файла
}
defer
обычно используется для освобождения ресурсов, использованных
в ходе работы функции. Можно использовать defer
несколько раз внути одной функции,
при этом код указанный после defer
будет вызываться в обратном порядке после завершения
работы функции. То есть код, указанный после первого defer
, будет вызван последним.