GO语言基础:函数定义、匿名函数、递归函数、多返回值、函数作为参数或返回值

5 阅读4分钟

2. 函数定义

在 Go 中,函数使用 func 关键字定义,基本语法:

func 函数名(参数列表) (返回值列表) {
    // 函数体
}
  • 参数列表:每个参数由参数名和类型组成,多个参数用逗号分隔。如果多个参数类型相同,可以省略前面的类型。
  • 返回值列表:可以没有返回值,也可以有一个或多个返回值。如果有多个返回值,需要用括号括起来,并指定类型。

示例:

// 无返回值
func PrintHello() {
    fmt.Println("Hello")
}

// 一个参数
func Double(x int) {
    fmt.Println(x * 2)
}

// 多个参数,相同类型可以简写
func Add(a, b int) int {
    return a + b
}

// 多个返回值
func Divide(a, b int) (int, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为0")
    }
    return a / b, nil
}

3. 多返回值

Go 语言的一个特色是函数可以返回多个值,这在处理错误时非常常见。通常,最后一个返回值用于返回错误信息。

package main

import "fmt"

func Swap(a, b string) (string, string) {
    return b, a
}

func main() {
    x, y := Swap("hello", "world")
    fmt.Println(x, y) // 输出:world hello
}

错误处理示例:

func SafeDivide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("division by zero")
    }
    return a / b, nil
}

func main() {
    result, err := SafeDivide(10, 0)
    if err != nil {
        fmt.Println("出错了:", err)
    } else {
        fmt.Println("结果:", result)
    }
}

4. 匿名函数

匿名函数就是没有名字的函数,通常用于需要临时定义一段逻辑的场景,比如赋值给变量、作为参数传递,或者立即执行。

定义并赋值给变量:

package main

import "fmt"

func main() {
    // 将匿名函数赋值给变量
    add := func(a, b int) int {
        return a + b
    }

    result := add(3, 4)
    fmt.Println(result) // 输出:7
}

立即执行(IIFE):

func main() {
    // 定义并立即调用
    sum := func(a, b int) int {
        return a + b
    }(10, 20)
    fmt.Println(sum) // 输出:30
}

匿名函数在 Go 中非常灵活,常用于 goroutine、回调函数等。


5. 递归函数

递归函数就是在函数内部调用自身。使用递归要小心,必须有一个终止条件,否则会无限循环导致栈溢出。

经典例子:计算阶乘

package main

import "fmt"

func Factorial(n int) int {
    if n <= 1 {
        return 1
    }
    return n * Factorial(n-1)
}

func main() {
    fmt.Println(Factorial(5)) // 输出:120
}

另一个例子:斐波那契数列

func Fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return Fibonacci(n-1) + Fibonacci(n-2)
}

func main() {
    fmt.Println(Fibonacci(7)) // 输出:13
}

注意:递归可能效率不高,但代码简洁。


6. 函数作为参数或返回值

在 Go 中,函数是一等公民,也就是说函数可以像普通变量一样被传递、赋值,也可以作为其他函数的参数或返回值。

函数作为参数

package main

import "fmt"

// 定义一个函数,它接受一个函数作为参数
func Compute(a, b int, operation func(int, int) int) int {
    return operation(a, b)
}

func main() {
    add := func(x, y int) int { return x + y }
    sub := func(x, y int) int { return x - y }

    fmt.Println(Compute(10, 5, add)) // 输出:15
    fmt.Println(Compute(10, 5, sub)) // 输出:5
}

函数作为返回值

package main

import "fmt"

// 返回一个函数,该函数会将输入乘以 factor
func MultiplyBy(factor int) func(int) int {
    return func(x int) int {
        return x * factor
    }
}

func main() {
    double := MultiplyBy(2)
    triple := MultiplyBy(3)

    fmt.Println(double(5)) // 输出:10
    fmt.Println(triple(5)) // 输出:15
}

这种用法被称为高阶函数,可以实现很多灵活的设计模式,比如装饰器、中间件等。


总结

  • 函数是独立的代码块,方法是绑定到类型的函数。
  • 使用 func 定义函数,可以没有参数/返回值,也可以有多个返回值。
  • 多返回值常用于返回结果和错误。
  • 匿名函数没有名字,可以赋值、传递或立即执行。
  • 递归函数自己调用自己,必须要有终止条件。
  • 函数可以作为参数传递给另一个函数,也可以作为返回值返回,这是函数式编程的基础。