- Нет параметров по умолчанию
- Вызов внешних функций
- Встроенные и внешние пакеты
- Именование и доступность
- Множественные возвращаемые значения
Функции в Go объявляются с помощью ключевого слова func
. Пример простой функции умножения:
func multiply(x int, y int) int {
return x * y
}
Сигнатура функции состоит из следующих элементов:
func
— ключевое слово для объявления функции;multiply
— имя функции;(x int, y int)
— параметры с указанием типов. Если несколько параметров подряд имеют одинаковый тип, запись можно сократить:func multiply(x, y int) int
int
— возвращаемый тип;{ ... }
— тело функции.
В Go обязательно указывать тип каждого параметра и результат, язык не допускает неявных объявлений. Порядок тоже строгий — тип всегда идёт после имени параметра.
Нет параметров по умолчанию
В Go не поддерживаются параметры по умолчанию, в отличие от многих других языков программирования. То есть, если функция принимает два аргумента, вы обязаны передать оба значения при вызове.
В языках где нет параметров по умолчанию, часто, применяют подход с созданием функции-обертки, которая позволяет эмулировать это поведение. Допустим, у нас есть функция getGreeting(name, greeting string)
, которая формирует приветствие:
func GetGreeting(name string, greeting string) string {
return greeting + ", " + name
}
В Go нельзя сделать greeting необязательным, но мы можем создать обёртку:
// Обёртка: использует "Hello" как greeting по умолчанию
func GetGreetingDefault(name string) string {
return getGreeting(name, "Hello")
}
Вызов внешних функций
Функции, объявленные в одном и том же пакете, можно вызывать просто по имени:
func greet(name string) string {
return "Hello, " + name
}
func main() {
msg := greet("Hexlet")
fmt.Println(msg)
}
Если функция определена в другом пакете, её нужно вызывать с указанием имени пакета:
package main
import "fmt"
func main() {
fmt.Println("Hello from Hexlet")
}
Здесь Println
— функция из пакета fmt
. Мы обращаемся к ней как fmt.Println
, потому что она объявлена в другом пакете.
Встроенные и внешние пакеты
В Go есть встроенные пакеты — они входят в стандартную библиотеку. Например:
fmt
— для форматированного выводаstrings
— для работы со строкамиmath
— для базовой математикиtime
— для работы со временем
Эти пакеты можно подключать через import
без установки дополнительных зависимостей. Кроме встроенных, можно использовать внешние пакеты — они подключаются отдельно через систему модулей (go mod). Работа с внешними пакетами рассматривается в соответствующем курсе на Хекслете.
Именование и доступность
Именование функций в Go следует стилю camelCase. Это означает, что имена пишутся слитно, а каждое новое слово в имени начинается с заглавной буквы: printMessage
, processData
, sendEmail
.
С первой буквой в названиях все чуть сложнее. Ее регистр определяет доступность функции снаружи пакета. Если имя начинается с заглавной буквы, функция доступна из других пакетов (экспортируемая). Если с маленькой, она остаётся внутри текущего пакета.
package math
func Multiply(x, y int) int {
// публичная
// экспортируемая функция, доступна как math.Multiply(...)
}
func divide(x, y int) int {
// приватная
// неэкспортируемая функция, доступна только внутри math
}
Так устроена видимость по аналогии с модификаторами доступа в других языках, но без ключевых слов вроде public или private — всё управляется регистром первой буквы.
Множественные возвращаемые значения
Go поддерживает возвращение нескольких значений из функции. Наиболее частый сценарий — возврат результата и ошибки. Работу с ошибками мы рассмотрим чуть позже, здесь же код дается просто понимания идеи.
func divide(x, y int) (int, error) {
if y == 0 {
return 0, errors.New("cannot divide by zero")
}
return x / y, nil
}
Здесь функция возвращает два значения: результат деления и объект ошибки (или nil, если ошибки нет). Сигнатура функции теперь содержит несколько типов в круглых скобках после func divide(...)
— в данном случае это (int, error)
.
Такой подход заменяет исключения (try/catch)
и делает обработку ошибок явной. Go заставляет вызывать сторону явно проверять возвращаемую ошибку, что снижает вероятность игнорирования важных условий.