Вступление
Function - это фрагмент кода, который после определения можно использовать повторно. Функции используются для того, чтобы облегчить понимание вашего кода, разбив его на небольшие понятные задачи, которые можно использовать более одного раза в вашей программе.
Go поставляется с мощной стандартной библиотекой, которая имеет много предопределенных функций. С пакетом fmt вы, вероятно, уже знакомы:
-
+ fmt.Println () +, который выводит объекты на стандартный вывод (скорее всего, ваш терминал). -
+ fmt.Printf () +, который позволит вам отформатировать вывод на печать.
Имена функций включают круглые скобки и могут включать параметры.
В этом уроке мы рассмотрим, как определить свои собственные функции для использования в ваших проектах кодирования.
Определение функции
Давайте начнем с превращения классической программы https://www.digitalocean.com/community/tutorials/how-to-write-your-first-program-in-go[icHello, World! »В функцию.
Мы создадим новый текстовый файл в нашем текстовом редакторе и вызовем программу + hello.go +. Затем мы определим функцию.
Функция определяется с помощью ключевого слова + func +. Затем следует имя по вашему выбору и набор скобок, которые содержат любые параметры, которые примет функция (они могут быть пустыми). Строки кода функции заключены в фигурные скобки + {} +.
В этом случае мы определим функцию с именем + hello () +:
hello.go
func hello() {}
Это устанавливает начальный оператор для создания функции.
Отсюда мы добавим вторую строку, чтобы предоставить инструкции о том, что делает функция. В этом случае мы будем печатать + Hello, World! + На консоли:
hello.go
func hello() {
fmt.Println("Hello, World!")
}
Наша функция теперь полностью определена, но если мы запустим программу на этом этапе, ничего не произойдет, так как мы не вызывали функцию.
Итак, внутри нашего функционального блока + main () + давайте вызовем функцию с помощью + hello () +:
hello.go
package main
import "fmt"
func main() {
hello()
}
func hello() {
fmt.Println("Hello, World!")
}
Теперь давайте запустим программу:
go run hello.go
Вы получите следующий вывод:
OutputHello, World!
Обратите внимание, что мы также ввели функцию с именем + main () +. Функция + main () + - это специальная функция, которая сообщает компилятору, что именно здесь программа должна * запуститься *. Для любой программы, которой вы хотите быть executable (программа, которую можно запустить из командной строки), вам понадобится функция + main () +. Функция + main () + должна появляться только один раз, находиться в + main () + package, получать и не возвращать аргументы. Это позволяет выполнять program в любой программе Go. Согласно следующему примеру:
main.go
package main
import "fmt"
func main() {
fmt.Println("this is the main section of the program")
}
Функции могут быть более сложными, чем определенная нами функция + hello () +. Мы можем использовать https://www.digitalocean.com/community/tutorials/how-to-construct-for-loops-in-go [+ for + loops], https://www.digitalocean.com/community/ учебные пособия / как написать условные операторы в условных выражениях и многое другое в нашем функциональном блоке.
Например, следующая функция использует условный оператор, чтобы проверить, содержит ли вход для переменной + name + гласный, а затем использует цикл + for + для перебора букв в строке + name +.
names.go
package main
import (
"fmt"
"strings"
)
func main() {
names()
}
func names() {
fmt.Println("Enter your name:")
var name string
fmt.Scanln(&name)
// Check whether name has a vowel
for _, v := range strings.ToLower(name) {
if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
fmt.Println("Your name contains a vowel.")
return
}
}
fmt.Println("Your name does not contain a vowel.")
}
Функция + names () +, которую мы здесь определяем, устанавливает переменную + name с вводом, а затем устанавливает условный оператор в цикле` + for`. Это показывает, как код может быть организован в определении функции. Однако, в зависимости от того, что мы собираемся сделать с нашей программой и как мы хотим настроить наш код, мы можем захотеть определить условный оператор и цикл + for + как две отдельные функции.
Определение функций в программе делает наш код модульным и многократно используемым, чтобы мы могли вызывать одни и те же функции, не переписывая их.
Работа с параметрами
До сих пор мы рассматривали функции с пустыми скобками, которые не принимают аргументов, но мы можем определить параметры в определениях функций в их скобках.
Parameter - это именованная сущность в определении функции, указывающая аргумент, который может принимать функция. В Go вы должны указать data type для каждого параметра.
Давайте создадим программу, которая повторяет слово определенное количество раз. Для повторения слова потребуется параметр + string с именем` + word n` и параметр + int с именем` + reps`.
repeat.go
package main
import "fmt"
func main() {
repeat("Sammy", 5)
}
func repeat(word string, reps int) {
for i := 0; i < reps; i++ {
fmt.Print(word)
}
}
Мы передали значение + Sammy + для параметра + word + и + 5 + для параметра + reps +. Эти значения соответствуют каждому параметру в том порядке, в котором они были заданы. Функция + repeat + имеет цикл + for +, который будет повторять количество раз, указанное параметром + reps +. Для каждой итерации выводится значение параметра + word +.
Вот вывод программы:
OutputSammySammySammySammySammy
Если у вас есть набор параметров с одинаковыми значениями, вы можете не указывать тип каждый раз. Давайте создадим небольшую программу, которая принимает параметры + x +, + y + и + z +, которые являются значениями + int +. Мы создадим функцию, которая добавляет параметры вместе в разных конфигурациях. Их суммы будут напечатаны функцией. Затем мы вызовем функцию и передадим числа в функцию.
add_numbers.go
package main
import "fmt"
func main() {
addNumbers(1, 2, 3)
}
func addNumbers(x, y, z int) {
a := x + y
b := x + z
c := y + z
fmt.Println(a, b, c)
}
Когда мы создали сигнатуру функции для + addNumbers +, нам не нужно было указывать тип каждый раз, а только в конце.
Мы передали число + 1 + для параметра + x +, + 2 + для параметра + y + и + 3 + для параметра + z +. Эти значения соответствуют каждому параметру в указанном порядке.
Программа выполняет следующую математику на основе значений, которые мы передали параметрам:
a = 1 + 2
b = 1 + 3
c = 2 + 3
Функция также печатает + a +, + b + и + c +, и исходя из этой математики, мы ожидаем, что + a + будет равно + 3 +, + b + будет + 4 + `и + c + , чтобы быть + 5 + `. Давайте запустим программу:
go run add_numbers.go
Output3 4 5
Когда мы передаем + 1 +, + 2 + и + 3 + в качестве параметров в функцию + addNumbers () +, мы получаем ожидаемый результат.
Параметры - это аргументы, которые обычно определяются как переменные в определениях функций. Им могут быть присвоены значения при запуске метода, передавая аргументы в функцию.
Возврат значения
Вы можете передать значение параметра в функцию, и функция также может создать значение.
Функция может создать значение с помощью оператора + return +, который завершит работу функции и опционально передаст выражение вызывающей стороне. Тип возвращаемых данных также должен быть указан.
До сих пор мы использовали оператор + fmt.Println () + вместо оператора + return + в наших функциях. Давайте создадим программу, которая вместо печати будет возвращать переменную.
В новом текстовом файле с именем + double.go + мы создадим программу, которая удваивает параметр + x + и возвращает переменную + y +. Мы вызываем вызов для печати переменной + result +, которая формируется путем запуска функции + double () + с передачей в нее + 3 +:
double.go
package main
import "fmt"
func main() {
result := double(3)
fmt.Println(result)
}
func double(x int) int {
y := x * 2
return y
}
Мы можем запустить программу и посмотреть вывод:
go run double.go
Output6
В качестве выходных данных возвращается целое число + 6 +, чего мы и ожидаем, умножив + 3 + на + 2 +.
Если функция указывает возврат, вы должны предоставить возврат как часть кода. Если вы этого не сделаете, вы получите ошибку компиляции.
Мы можем продемонстрировать это, закомментировав строку с помощью оператора return:
double.go
package main
import "fmt"
func main() {
result := double(3)
fmt.Println(result)
}
func double(x int) int {
y := x * 2
// return y
}
Теперь давайте снова запустим программу:
go run double.go
Output./double.go:13:1: missing return at end of function
Без использования оператора + return + программа не может скомпилироваться.
Функции завершаются немедленно, когда они нажимают оператор + return +, даже если они не находятся в конце функции:
return_loop.go
package main
import "fmt"
func main() {
loopFive()
}
func loopFive() {
for i := 0; i < 25; i++ {
fmt.Print(i)
if i == 5 {
// Stop function at i == 5
return
}
}
fmt.Println("This line will not execute.")
}
Здесь мы повторяем цикл + for + и говорим циклу запускать итерации + 25 +. Однако внутри цикла + for у нас есть условный оператор` + if`, который проверяет, равно ли значение + i + + 5 +. Если это так, мы запускаем оператор + return +. Поскольку мы находимся в функции + loop Five, и` + return` в любой точке функции выйдет из функции. В результате мы никогда не доберемся до последней строки в этой функции, чтобы напечатать оператор + Эта строка не будет выполняться. +.
Использование оператора + return внутри цикла` + for` завершает функцию, поэтому строка, находящаяся вне цикла, не будет выполняться. Если бы вместо этого мы использовали https://www.digitalocean.com/community/tutorials/how-to-use-break-and-continue-statements-when-working-with-loops-in-go#break- оператор [+ break + оператор], в это время мог бы выйти только цикл, и запустилась бы последняя строка + fmt.Println () +.
Оператор + return + выходит из функции и может возвращать значение, если оно указано в сигнатуре функции.
Возврат нескольких значений
Для функции может быть указано более одного возвращаемого значения. Давайте рассмотрим программу + repeat.go + и сделаем так, чтобы она возвращала два значения. Первое будет повторным значением, а второе будет ошибкой, если параметр + reps + не является значением больше, чем + 0 +:
repeat.go
package main
import "fmt"
func main() {
val, err := repeat("Sammy", -1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(val)
}
func repeat(word string, reps int) (string, error) {
if reps <= 0 {
return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
}
var value string
for i := 0; i < reps; i++ {
value = value + word
}
return value, nil
}
Первое, что делает функция + repeat +, это проверяет, является ли аргумент + reps + допустимым значением. Любое значение, которое не больше + 0 +, приведет к ошибке. Поскольку мы передали значение + -1 +, эта ветвь кода будет выполнена. Обратите внимание, что когда мы возвращаемся из функции, мы должны предоставить оба возвращаемых значения: + string + и + error +. Поскольку предоставленные аргументы привели к ошибке, мы передадим обратно пустую строку для первого возвращаемого значения и ошибку для второго возвращаемого значения.
В функции + main () + мы можем получить оба возвращаемых значения, объявив две новые переменные, + value + и + err +. Поскольку в возвращении может быть ошибка, мы хотим проверить, не получили ли мы ошибку, прежде чем продолжить нашу программу. В этом примере мы получили ошибку. Мы выводим ошибку и + return + из функции + main () + для выхода из программы.
Если бы не было ошибки, мы бы распечатали возвращаемое значение функции.
Запуск программы приведет к следующему выводу:
Outputinvalid value of -1 provided for reps. value must be greater than 0.
В этом разделе мы рассмотрели, как мы можем использовать оператор + return + для возврата нескольких значений из функции.
Заключение
Функции - это кодовые блоки инструкций, которые выполняют действия внутри программы, помогая сделать наш код многоразовым и модульным.
Чтобы узнать больше о том, как сделать ваш код более модульным, вы можете прочитать наше руководство на Как писать пакеты в Go .