Вступление
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 .