如何在 Go 中定义和调用函数

介绍

function 是一个代码的部分,一旦定义,可以重复使用. 函数被用来使您的代码更容易理解,通过将其分解为小、易于理解的任务,可以在整个程序中多次使用。

Go船有强大的标准库,有许多预定义的功能. 那些你可能已经熟悉从 fmt包是:

  • fmt.Println() 将打印对象以标准化(最有可能是您的终端)。

函数名包括关节,并可能包括参数。

在本教程中,我们将讨论如何在您的编码项目中定义自己的函数。

定义一个函数

让我们先把经典的)变成一个函数。

我们将在我们所选择的文本编辑器中创建一个新的文本文件,并将该程序称为hello.go

一个函数是通过使用)的关节组合。

在这种情况下,我们将定义一个名为hello()的函数:

1[label hello.go]
2func hello() {}

此设置了创建函数的初始语句。

从这里开始,我们将添加第二行以提供该函数所需的指示,在这种情况下,我们将打印Hello, World!到控制台:

1[label hello.go]
2func hello() {
3    fmt.Println("Hello, World!")
4}

我们的函数现在已经完全定义了,但如果我们在这个时候运行该程序,就不会发生什么,因为我们没有调用该函数。

所以,在我们的)`来调用函数:

 1[label hello.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    hello()
 8}
 9
10func hello() {
11    fmt.Println("Hello, World!")
12}

现在,让我们运行这个程序:

1go run hello.go

您将收到以下输出:

1[secondary_label Output]
2Hello, World!

通知:我们还引入了一个名为 " main() " 的函数。 ‘main ()' 函数是一个特殊函数,它告诉编译器,程序应该在这里启动 . 对于任何想要被_可执行_的程序(一个可以从命令行运行的程序),您需要)' 函数必须只显示一次,在`main ()' -- -- package -- -- 中,接收和返回任何论据。 这允许任何 Go 程序中的 [程序执行] (https://golang.org/ref/spec# Program_execution] 。 例如:

1[label main.go]
2package main
3
4import "fmt"
5
6func main() {
7    fmt.Println("this is the main section of the program")
8}

我们可以使用(https://andsky.com/tech/tutorials/how-to-construct-for-loops-in-go),(https://andsky.com/tech/tutorials/how-to-write-conditional-statements-in-go),以及更多在我们的函数块内。

例如,下列函数使用条件语句来检查名称变量的输入是否包含语音,然后使用循环重复名称字符串中的字母。

 1[label names.go]
 2package main
 3
 4import (
 5    "fmt"
 6    "strings"
 7)
 8
 9func main() {
10    names()
11}
12
13func names() {
14    fmt.Println("Enter your name:")
15
16    var name string
17    fmt.Scanln(&name)
18    // Check whether name has a vowel
19    for _, v := range strings.ToLower(name) {
20    	if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' {
21    		fmt.Println("Your name contains a vowel.")
22    		return
23    	}
24    }
25    fmt.Println("Your name does not contain a vowel.")
26}

我们在这里定义的名称()函数会设置一个名称变量与输入,然后在for循环中设置一个条件陈述. 这表明代码如何在函数定义中进行组织。

在程序中定义函数使我们的代码模块化和可重复使用,以便我们可以调用相同的函数而不重写它们。

工作与参数

到目前为止,我们已经研究了没有参数的空格符串的函数,但我们可以在它们的符串中定义函数定义中的参数。

在 Go 中,您必须为每个参数指定 data type

让我们创建一个程序,重复一个单词一个特定的次数,它将需要一个名为字符串参数和一个名为repsint参数来重复这个单词的次数。

 1[label repeat.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    repeat("Sammy", 5)
 8}
 9
10func repeat(word string, reps int) {
11    for i := 0; i < reps; i++ {
12    	fmt.Print(word)
13    }
14}

我们输入了Sammy值为word参数和5reps参数,这些值以它们所给出的顺序对应于每个参数。repeat函数有一个for循环,它会重复reps参数所指定的次数。

以下是该计划的结果:

1[secondary_label Output]
2SammySammySammySammySammy

如果你有一套具有相同值的参数,你可以忽略每次指定类型。让我们创建一个小程序,其中包括参数x,yz,这些参数都是int值。我们将创建一个函数,在不同的配置中将参数合并在一起。这些参数的总和将由函数打印出来。

 1[label add_numbers.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    addNumbers(1, 2, 3)
 8}
 9
10func addNumbers(x, y, z int) {
11    a := x + y
12    b := x + z
13    c := y + z
14    fmt.Println(a, b, c)
15}

当我们为addNumbers创建函数签名时,我们不需要每次指定类型,而只是在最后。

我们输入了1x参数,2y参数,3z参数。

该程序基于我们传递给参数的值来做以下数学:

1a = 1 + 2
2b = 1 + 3
3c = 2 + 3

函数还打印了a,bc,基于这个数学,我们希望a等于3,b等于4,c等于5

1go run add_numbers.go
1[secondary_label Output]
23 4 5

当我们将)`函数时,我们会收到预期的输出。

参数是通常在函数定义中定义为变量的参数,在运行方法时可以分配值,将参数传入函数中。

返回值

您可以将参数值传输到函数中,并且函数也可以产生值。

函数可以通过返回语句生成一个值,该语句将退出函数并可选地将一个表达式传回呼叫器。

到目前为止,我们在我们的函数中使用了fmt.Println()语句而不是return语句,让我们创建一个程序,而不是打印,它会返回一个变量。

在一个名为double.go的新文本文件中,我们将创建一个程序,将参数x加倍并返回变量y

 1[label double.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    result := double(3)
 8    fmt.Println(result)
 9}
10
11func double(x int) int {
12    y := x * 2
13    return y
14}

我们可以运行程序并查看输出:

1go run double.go
1[secondary_label Output]
26

整数6作为输出返回,这就是我们将3乘以2所期望的。

如果函数指定返回,则必须作为代码的一部分提供返回;如果没有,则会收到编译错误。

我们可以通过评论与返回声明的行来证明这一点:

 1[label double.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    result := double(3)
 8    fmt.Println(result)
 9}
10
11func double(x int) int {
12    y := x * 2
13    // return y
14}

现在,让我们再次运行程序:

1go run double.go
1[secondary_label Output]
2./double.go:13:1: missing return at end of function

在这里没有使用返回声明,程序无法编译。

函数在击中一个返回语句时立即退出,即使它们不在函数的末尾:

 1[label return_loop.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    loopFive()
 8}
 9
10func loopFive() {
11    for i := 0; i < 25; i++ {
12    	fmt.Print(i)
13    	if i == 5 {
14    		// Stop function at i == 5
15    		return
16    	}
17    }
18    fmt.Println("This line will not execute.")
19}

在这里,我们通过一个for循环进行迭代,并告诉循环运行25迭代。然而,在for循环中,我们有一个有条件的if陈述来检查i的值是否等于5。如果是,我们发出一个return陈述。因为我们处于loopFive函数中,函数中的任何一个点的return都会离开函数。因此,我们从来没有到达这个函数的最后一行来打印这条线不会执行

如果,相反,我们使用了 break 语句,只有循环在那个时候会离开,最后一个 fmt.Println() 行会运行。

返回语句退出一个函数,如果在函数签名中指定,则可以返回一个值。

返回多重值

一个函数可以指定多于一个返回值. 让我们检查repeat.go程序,让它返回两个值. 第一个值是重复值,第二个值是错误,如果reps参数不大于0:

 1[label repeat.go]
 2package main
 3
 4import "fmt"
 5
 6func main() {
 7    val, err := repeat("Sammy", -1)
 8    if err != nil {
 9    	fmt.Println(err)
10    	return
11    }
12    fmt.Println(val)
13}
14
15func repeat(word string, reps int) (string, error) {
16    if reps <= 0 {
17    	return "", fmt.Errorf("invalid value of %d provided for reps. value must be greater than 0.", reps)
18    }
19    var value string
20    for i := 0; i < reps; i++ {
21    	value = value + word
22    }
23    return value, nil
24}

重复函数做的第一件事是检查重复参数是否是有效的值,任何不大于0的值都会造成错误,因为我们通过了-1值,这个代码分支将执行。请注意,当我们从函数返回时,我们必须提供字符串错误返回值。

main()函数中,我们可以通过声明两个新的变量err来获得两个返回值,因为返回中可能有错误,所以我们希望在继续使用我们的程序之前检查是否收到错误。

如果没有错误,我们会打印函数的返回值。

<$>[注] 注: 仅返回两个或三个值被认为是最佳的做法,此外,您应该始终返回所有错误作为函数的最后返回值。

运行该程序将产生以下输出:

1[secondary_label Output]
2invalid value of -1 provided for reps. value must be greater than 0.

在本节中,我们审查了如何使用返回语句来返回函数中的多个值。

结论

函数是指令的代码块,在程序中执行操作,有助于使我们的代码可重复使用和模块化。

要了解更多有关如何使您的代码更模块化,您可以阅读我们的指南在 如何在Go中写包

Published At
Categories with 技术
Tagged with
comments powered by Disqus