Skip to content

函数

基本函数定义

无返回值函数

go
func sayHello() {
    fmt.Println("Hello, Go!")
}

有返回值函数

go
func add(a int, b int) int {
    return a + b
}

// 相同类型参数简写
func add2(a, b int) int {
    return a + b
}

命名返回值

go
func divide(a, b float64) (result float64) {
    result = a / b
    return  // 等价于 return result
}

多返回值

Go函数可以返回多个值:

go
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为0")
    }
    return a / b, nil
}

函数调用示例

go
package main

import "fmt"

func main() {
    sayHello()
    
    result := add(5, 3)
    fmt.Println("5 + 3 =", result)
    
    quotient, err := divide(10, 2)
    if err != nil {
        fmt.Println("错误:", err)
        return
    }
    fmt.Println("10 / 2 =", quotient)
}

func sayHello() {
    fmt.Println("Hello, Go!")
}

func add(a int, 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
}

可变参数

go
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

func main() {
    fmt.Println(sum(1, 2, 3))           // 6
    fmt.Println(sum(1, 2, 3, 4, 5))     // 15
    
    // 传递切片
    nums := []int{1, 2, 3, 4}
    fmt.Println(sum(nums...))           // 10
}

匿名函数和闭包

匿名函数

go
func main() {
    // 定义并调用匿名函数
    func() {
        fmt.Println("匿名函数")
    }()
    
    // 带参数的匿名函数
    func(name string) {
        fmt.Println("Hello,", name)
    }("Go")
    
    // 赋值给变量
    add := func(a, b int) int {
        return a + b
    }
    fmt.Println(add(1, 2))  // 3
}

闭包

闭包是一个函数值,它引用了函数体之外的变量:

go
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    c := counter()
    fmt.Println(c())  // 1
    fmt.Println(c())  // 2
    fmt.Println(c())  // 3
    
    c2 := counter()
    fmt.Println(c2()) // 1 (新的计数器)
}

函数作为参数

go
func apply(nums []int, fn func(int) int) []int {
    result := make([]int, len(nums))
    for i, num := range nums {
        result[i] = fn(num)
    }
    return result
}

func main() {
    nums := []int{1, 2, 3, 4, 5}
    
    // 传入匿名函数
    doubled := apply(nums, func(n int) int {
        return n * 2
    })
    fmt.Println(doubled)  // [2 4 6 8 10]
    
    // 传入已定义的函数
    squared := apply(nums, square)
    fmt.Println(squared)  // [1 4 9 16 25]
}

func square(n int) int {
    return n * n
}

函数作为返回值

go
func getCalculator(op string) func(int, int) int {
    switch op {
    case "add":
        return func(a, b int) int { return a + b }
    case "sub":
        return func(a, b int) int { return a - b }
    case "mul":
        return func(a, b int) int { return a * b }
    default:
        return func(a, b int) int { return 0 }
    }
}

func main() {
    add := getCalculator("add")
    fmt.Println(add(5, 3))  // 8
    
    mul := getCalculator("mul")
    fmt.Println(mul(5, 3))  // 15
}

defer语句

defer 用于延迟执行函数,通常用于资源清理:

go
func main() {
    fmt.Println("开始")
    defer fmt.Println("延迟1")
    defer fmt.Println("延迟2")
    fmt.Println("结束")
}
// 输出顺序: 开始 -> 结束 -> 延迟2 -> 延迟1

实际应用

go
func readFile(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer file.Close()  // 确保文件关闭
    
    // 读取文件操作...
    return nil
}

defer与返回值

go
func deferExample() (result int) {
    defer func() {
        result++  // 修改命名返回值
    }()
    return 5  // 返回6
}

init函数

每个包可以有一个 init 函数,在包加载时自动执行:

go
package main

import "fmt"

var name string

func init() {
    name = "Go语言"
    fmt.Println("init函数执行")
}

func main() {
    fmt.Println("main函数执行")
    fmt.Println("name:", name)
}
// 输出顺序: init函数执行 -> main函数执行 -> name: Go语言

递归函数

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

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

func main() {
    fmt.Println(factorial(5))    // 120
    fmt.Println(fibonacci(10))   // 55
}