首页 > 编程笔记

Go语言函数的定义和调用

几乎所有的高级语言都支持函数或类似函数的编程结构。函数是程序执行的一个基本语法结构,Go 语言的很多特性是基于函数实现的。

我们已经认识了 main() 函数,main() 函数是程序的入口,由于 Go 语言是编译型语言,所以,函数编写的顺序是无关紧要的,但为了可读性,通常把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(函数被调用的顺序、函数的用途等)即可。

Go 语言的标准库提供了许多种内置的函数。例如,len() 函数可以接收不同类型的参数并返回该类型的长度。如果传入的是字符串,则返回字符串的长度;如果传入的是数组,则返回数组中包含的元素个数。

接下来,将带领读者认识一下 Go 语言的函数。

函数的声明

函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段,它可以提高应用的模块性和代码的重复利用率。

函数是 Go 语言程序源代码的基本构造单位,一个函数的定义包括以下几个部分:
函数名遵循标识符的命名规则,首字母的大小写决定该函数在其他包的可见性:大写时其他包可见,小写时只有相同的包可以访问;函数的参数和返回值需要使用“( )”,如果只有一个返回值,而且使用的是非命名的参数,则返回参数的“( )”可以省略。函数体使用“{ }”,并且“{”必须位于函数返回值同行的行尾。

Go语言函数声明的语法格式如下:
func 函数名(参数列表)(返回参数列表){
    函数体
}
1) func:函数由 func 开始声明。

2) 函数名:由字母、数字、下画线组成。其中,函数名的第一个字母不能为数字,在同一个包内,函数名称不能重复。

3) 参数列表:一个参数由参数变量和参数类型组成,参数列表中的变量作为函数的局部变量而存在。

4) 返回参数列表:可以是返回值类型列表,也可以是类似参数列表中变量名和类型名的组合。函数在声明有返回值时,必须在函数体中使用 return 语句提供返回值列表。如果函数返回一个无名变量或者没有返回值,返回参数列表的括号是可以省略的。

5) 函数体:能够被重复调用的代码片段。

例如:
func main() {
    sum := add(1,2)
    fmt.Println(sum)
}
func add(a,b int) int {
    return a+b
}
以上代码中定义了 add() 函数,它的函数声明是func add(a,b int) int,直接定义在一个包之下,main() 函数可以直接调用 add() 函数。

声明一个在外部定义的函数只需给出函数名与函数签名即可,不需要写出完整的函数体,例如:
func hello(str,num int)  //外部实现
函数同样可以通过声明的方式作为一个函数类型被使用,例如:
type addNum func (int, int)int
此处不需要函数体“{ }”,因为函数在 Go 语言中属于一等值(frst-class value),函数也可以赋值给变量,如add := addNum,由于变量指向了 addNum 函数的签名,所以,不能再给它赋一个具有不同签名的函数值。

不过函数值(functions value)之间倒是可以相互比较的,例如,它们引用的是相同的函数或者返回值都是 nil,则可以认为它们是相同的函数。函数不能在其他函数中声明,也就是不能嵌套(匿名函数除外)。

函数的特点可以总结为以下几点:
1) 函数可以没有输入参数,也可以没有返回值(默认为 0)。

2) 多个相邻的相同类型的参数可以使用简写模式,例如:
func add(a int,b int) int {
    return a+b
}
简写为
func add(a,b int) int {
    return a+b
}

3) 支持有名的返回值,参数名相当于函数体内最外层的局部变量,命名返回值变量会被初始化为类型零值,最后的 return 可以不带参数名直接返回。

4) 不支持默认值参数。

5) 不支持函数重载。

6) 不支持函数嵌套,严格来说是不支持命名函数的嵌套,但支持嵌套匿名函数。

函数的调用

函数在声明后,可以通过调用的方式,让当前代码跳转到被调用的函数中执行,调用前的函数局部变量都会被保存起来不会丢失,被调用的函数运行结束后,恢复到调用函数的下一行继续执行代码,之前的局部变量也能继续访问。

函数内的局部变量只能在函数体中使用,函数调用结束后,这些局部变量都会被释放并且失效。

Go 语言函数调用的语法格式如下:
返回值变量列表 = 函数名(参数列表)

当创建函数时,定义了函数需要做什么,通常需要调用该函数来执行指定任务。例如,调用函数,向函数传递参数,并返回值。
package main
import "fmt"
func main() {
   /*定义局部变量*/
   var a int = 100
   var b int = 200
   var ret int
   /*调用函数并返回最大值*/
   ret = max(a, b)
   fmt.Printf( "最大值是 : %d\n", ret )
}
/*函数返回两个数的最大值*/
func max(num1, num2 int) int {
   /*定义局部变量*/
   var result int
   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result
}
以上代码中,在 main() 函数中调用了 max() 函数,运行结果如下:

最大值是 : 200

推荐阅读