Go 语言函数(Functions)详解
在 Go 语言中,函数是程序的基本构建块之一。函数用于封装可重用的代码逻辑,它有输入(参数)、处理(函数体)和输出(返回值)。
1. Go 语言函数基本结构
Go 语言的函数由以下部分组成:
- 函数声明:包括
func关键字、函数名、参数列表、返回值列表以及函数体。 - 函数体:包含实际的代码逻辑。
1.1 语法
func 函数名(参数列表) 返回值类型 {
// 函数体
return 返回值
}
1.2 示例
package main
import "fmt"
// 定义一个简单的函数,计算两个数的和
func add(a int, b int) int {
return a + b
}
func main() {
result := add(10, 20) // 调用函数
fmt.Println("和:", result)
}
输出:
和: 30
2. 函数参数
2.1 单一参数
每个参数都需要指定类型。
func greet(name string) {
fmt.Println("Hello, " + name)
}
2.2 多个参数
多个参数可以一起声明,参数类型与类型名称用逗号分隔。
func add(a int, b int) int {
return a + b
}
2.3 可变参数
Go 支持可变数量的参数。使用 ... 来定义可变参数。可变参数可以接收传入的任意数量的值。
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
result := sum(1, 2, 3, 4, 5)
fmt.Println("总和:", result)
}
输出:
总和: 15
3. 函数返回值
3.1 单一返回值
Go 语言函数可以有一个返回值。
func multiply(a int, b int) int {
return a * b
}
3.2 多个返回值
Go 语言允许函数返回多个值。这对于返回错误或者多个相关的值非常有用。
func divide(a, b int) (int, int) {
return a / b, a % b // 返回商和余数
}
func main() {
quotient, remainder := divide(10, 3)
fmt.Println("商:", quotient, "余数:", remainder)
}
输出:
商: 3 余数: 1
3.3 命名返回值
在 Go 中,我们可以为返回值命名。这样做的好处是函数可以直接使用命名的返回值,而无需在函数体中显式地写出 return。
func getDimensions() (width, height int) {
width = 10
height = 5
return // 自动返回命名的值
}
4. 函数作为值
在 Go 语言中,函数是一等公民,可以将函数赋值给变量,作为参数传递给其他函数,甚至作为返回值返回。
4.1 函数赋值
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
var sumFunc func(int, int) int
sumFunc = add
result := sumFunc(10, 20) // 调用函数
fmt.Println("和:", result)
}
输出:
和: 30
4.2 函数作为参数
函数可以作为其他函数的参数传递。
package main
import "fmt"
func calculate(a, b int, operation func(int, int) int) int {
return operation(a, b)
}
func add(a, b int) int {
return a + b
}
func main() {
result := calculate(10, 20, add) // 传递函数作为参数
fmt.Println("和:", result)
}
输出:
和: 30
4.3 函数作为返回值
Go 语言函数可以返回另一个函数。这在实现闭包时非常有用。
package main
import "fmt"
func multiplyBy(factor int) func(int) int {
return func(n int) int {
return n * factor
}
}
func main() {
multiplyBy2 := multiplyBy(2)
fmt.Println("10 * 2 =", multiplyBy2(10)) // 调用返回的函数
}
输出:
10 * 2 = 20
5. 匿名函数
Go 支持匿名函数(没有名字的函数),这在某些情况下非常方便,尤其是函数作为参数传递或者闭包。
5.1 匿名函数示例
package main
import "fmt"
func main() {
func() {
fmt.Println("这是一个匿名函数")
}() // 立即调用
}
输出:
这是一个匿名函数
6. 闭包(Closure)
闭包是一个函数,它捕获了外部函数的变量,即使外部函数已经返回,闭包依然能够访问这些变量。Go 中的函数作为一等公民使得闭包成为可能。
6.1 闭包示例
package main
import "fmt"
func outer() func() int {
counter := 0
return func() int {
counter++
return counter
}
}
func main() {
counterFunc := outer()
fmt.Println(counterFunc()) // 输出 1
fmt.Println(counterFunc()) // 输出 2
fmt.Println(counterFunc()) // 输出 3
}
输出:
1
2
3
7. 总结
| 特性 | 描述 |
|---|---|
| 函数声明 | func 函数名(参数列表) 返回值类型 {} |
| 返回值 | 可返回多个值,包括命名返回值 |
| 参数类型 | 可以是值类型或者引用类型 |
| 可变参数 | 使用 ... 语法来定义可变数量的参数 |
| 匿名函数 | 没有名字的函数,可以立即调用 |
| 函数作为值 | 函数可以赋值给变量,传递给其他函数或作为返回值 |
| 闭包 | 函数可以捕获其外部作用域的变量 |