Golang 中的函数是一组用于执行特定任务的代码块,借助函数可以使代码模块化。一个复杂的功能可以被分解为一块块小块的代码,然后可以由不同的人员在不同的时间编写。
函数定义
Golang 中的函数定义由关键字 func 开始,后面跟上函数名、参数列表和返回值列表。函数定义的基本语法如下:
func functionName(parameterList) (returnParameterList) {
// 函数体
}
具体含义如下:
- functionName:函数名称,用于标识该函数。
- parameterList:函数接受的参数列表,参数之间使用逗号分隔。如果没有输入参数,则使用空的括号。
- returnParameterList:函数返回的参数列表,参数之间使用逗号分隔。如果没有返回参数,不写即可。
- 函数体:包含实现函数功能的代码块。
以下是一个简单的函数定义示例代码:
func add(a, b int) int {
return a + b
}
函数可以接受零个或多个输入参数。这些参数在函数定义时指定,并在函数调用时传递。简单示例如下:
// 接受一个字符串类型参数
func printString(s string) {
fmt.Println(s)
}
// 接受两个整数类型参数
func add(a, b int) int {
return a + b
}
// 接受一个浮点数和一个整数类型参数
func divide(f float64, i int) float64 {
return f / float64(i)
}
在调用函数时,传给函数的实际参数必须与函数定义的参数数量和类型匹配。例如调用 add 函数的示例代码如下:
result := add(2, 3) // 调用add函数,传入两个整数类型参数2和3
fmt.Println(result) // 输出5
Golang 也支持可变参数,可变参数意味着函数可以接受不定数量参数。这些参数的类型和数量可以在运行时确定。可变参数在函数定义的参数列表中使用省略号(...)来表示。示例代码如下:
package main
import "fmt"
func println(args ...interface{}) {
for _, arg := range args {
fmt.Println(arg)
}
}
func main() {
println("Hello, ", "World!")
println("路多辛的博客", 42, true)
}
println 函数接受一个可变参数 args,在函数体中,循环遍历 args 并打印每个参数的值。然后在 main 函数中调用两次 println 函数,每次传递不同数量的参数。
函数可以返回零个或多个参数,这些参数在函数定义时指定,在函数调用时使用变量接收。简单示例如下:
// 返回一个字符串
func greet(name string) string {
return "Hello, " + name + "!"
}
// 返回两个整数
func add(a, b int) (int, int) {
return a + b, a - b
}
// 返回一个浮点数和一个整数
func multiply(f float64, i int) (float64, int) {
return f * float64(i), i
}
在函数调用时,可以使用变量来接收函数的返回参数。例如:
message := greet("路多辛") // 调用greet函数,接收返回的字符串参数 message
fmt.Println(message) // 输出 "Hello, 路多辛!"
main 函数
main 函数是一个特殊的函数,是程序的入口。main 函数必须定义在 main 包中,不接受任何参数,也没有返回值,每个程序有且只能有一个 main 函数。简单示例如下:
package main
import "fmt"
func main() {
fmt.Println("路多辛的所思所想!")
}
init 函数
init 函数也是一个特殊的函数,和 main 函数一样也是为 Go 编译器保留的特殊用途函数,不接受任何参数,也没有返回值。但是在一个程序中可以创建多个 init 函数,甚至每个文件中也可以创建多个 init 函数。
init 函数会在包内的任何代码块执行前先执行,init函数执行顺序如下:
如果多个包的中的 init 函数都要执行,首先会先按照包名的字段顺序执行(main 包除外,main 包内的 init 函数会等其它所有包中 init 函数执行后再执行),同一个包内的 init 函数按照所在文件的名字的字典顺序执行,同一个文件中的 init 函数按照创建的顺序执行。
闭包(匿名函数)
关于匿名函数和闭包的讲解可以参考之前的文章《Golang 中的闭包(Closures)详解》。
递归函数
调用自身的函数称为递归函数,相互调用的函数称为相互递归函数。递归函数的典型特征是当递归地调用自己时,必须具有终止条件,防止因为无限递归导致堆栈溢出。简单示例如下:
func fibonacci(num int) int {
if num < 2 {
return num
}
return fibonacci(num-1) + fibonacci(num-2)
}
小结
Golang 中的函数除了上面介绍的特点外,还有如下特点:
- 不支持函数重载
- 同一个包中函数名不能重复(init 函数除外)
- 不支持默认参数