现在位置: 首页 > Go 语言教程 > 正文

Go 语言函数作为实参

Go 函数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
}

以上代码执行结果为:

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
}

以上代码执行结果为:

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]
}

以上代码执行结果为:

升序:[1 2 3 5 8 9]
降序:[9 8 5 3 2 1]

通过将不同的函数作为实参传入,同一个 sort.Slice 就可以实现完全不同的排序逻辑,这正是函数作为实参的核心价值——将行为参数化,让代码更灵活复用

Go 函数Go 函数