Go 语言函数作为实参
Go 语言中,函数是一等公民(First-class citizen),可以像普通变量一样被赋值、传递和使用。将函数作为实参传递给另一个函数,是 Go 中常见的编程模式,常用于回调、策略模式等场景。
函数赋值给变量
函数可以赋值给一个变量,通过该变量来调用函数:
实例
package main
import (
"fmt"
"math"
)
func main() {
/* 将匿名函数赋值给变量 getSquareRoot */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 通过变量调用函数 */
fmt.Println(getSquareRoot(9)) // 输出:3
fmt.Println(getSquareRoot(16)) // 输出:4
}
import (
"fmt"
"math"
)
func main() {
/* 将匿名函数赋值给变量 getSquareRoot */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 通过变量调用函数 */
fmt.Println(getSquareRoot(9)) // 输出:3
fmt.Println(getSquareRoot(16)) // 输出:4
}
以上代码执行结果为:
3 4
函数作为实参传递
将函数作为实参传递给另一个函数时,接收方需要声明对应的函数类型参数。以下示例定义了一个 apply 函数,接收一个操作函数和两个操作数,对两个数执行任意指定的操作:
实例
package main
import (
"fmt"
"math"
)
/* 定义一个函数,接收一个函数类型的参数 op */
/* op 的类型为 func(float64, float64) float64,表示接受两个 float64 参数、返回 float64 的函数 */
func apply(op func(float64, float64) float64, a, b float64) float64 {
return op(a, b)
}
func main() {
/* 定义加法函数 */
add := func(a, b float64) float64 {
return a + b
}
/* 定义乘法函数 */
multiply := func(a, b float64) float64 {
return a * b
}
/* 将 add 函数作为实参传入 apply */
fmt.Println(apply(add, 3, 4)) // 输出:7
/* 将 multiply 函数作为实参传入 apply */
fmt.Println(apply(multiply, 3, 4)) // 输出:12
/* 也可以直接传入匿名函数 */
fmt.Println(apply(func(a, b float64) float64 {
return math.Pow(a, b) // a 的 b 次方
}, 2, 10)) // 输出:1024
}
import (
"fmt"
"math"
)
/* 定义一个函数,接收一个函数类型的参数 op */
/* op 的类型为 func(float64, float64) float64,表示接受两个 float64 参数、返回 float64 的函数 */
func apply(op func(float64, float64) float64, a, b float64) float64 {
return op(a, b)
}
func main() {
/* 定义加法函数 */
add := func(a, b float64) float64 {
return a + b
}
/* 定义乘法函数 */
multiply := func(a, b float64) float64 {
return a * b
}
/* 将 add 函数作为实参传入 apply */
fmt.Println(apply(add, 3, 4)) // 输出:7
/* 将 multiply 函数作为实参传入 apply */
fmt.Println(apply(multiply, 3, 4)) // 输出:12
/* 也可以直接传入匿名函数 */
fmt.Println(apply(func(a, b float64) float64 {
return math.Pow(a, b) // a 的 b 次方
}, 2, 10)) // 输出:1024
}
以上代码执行结果为:
7 12 1024
实际应用:自定义排序规则
函数作为实参最常见的应用之一是自定义排序规则。Go 标准库的 sort.Slice 就接受一个比较函数作为参数:
实例
package main
import (
"fmt"
"sort"
)
func main() {
nums := []int{5, 2, 8, 1, 9, 3}
/* 将比较函数作为实参传入 sort.Slice,实现从小到大排序 */
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
fmt.Println("升序:", nums) // 输出:升序:[1 2 3 5 8 9]
/* 传入不同的比较函数,实现从大到小排序 */
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
fmt.Println("降序:", nums) // 输出:降序:[9 8 5 3 2 1]
}
import (
"fmt"
"sort"
)
func main() {
nums := []int{5, 2, 8, 1, 9, 3}
/* 将比较函数作为实参传入 sort.Slice,实现从小到大排序 */
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
fmt.Println("升序:", nums) // 输出:升序:[1 2 3 5 8 9]
/* 传入不同的比较函数,实现从大到小排序 */
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
fmt.Println("降序:", nums) // 输出:降序:[9 8 5 3 2 1]
}
以上代码执行结果为:
升序:[1 2 3 5 8 9] 降序:[9 8 5 3 2 1]
通过将不同的函数作为实参传入,同一个 sort.Slice 就可以实现完全不同的排序逻辑,这正是函数作为实参的核心价值——将行为参数化,让代码更灵活复用。

Go 函数