Learn
Go/04-functions

函数

1. 基本定义

func add(a, b int) int {
    return a + b
}
基本函数
package main
 
import "fmt"
 
func add(a, b int) int {
    return a + b
}
 
func main() {
    fmt.Println(add(3, 5))
}

2. 多返回值

Go 函数可以返回任意数量的值,这是它处理错误的惯用方式。

多返回值
package main
 
import "fmt"
 
func div(a, b int) (int, int) {  // 商, 余数
    return a / b, a % b
}
 
func main() {
    q, r := div(17, 5)
    fmt.Printf("17 ÷ 5 = %d 余 %d\\n", q, r)
 
    // 只用其中一个,另一个用 _ 忽略
    onlyQ, _ := div(10, 3)
    fmt.Println("商:", onlyQ)
}

3. 命名返回值

返回值可以命名,函数体内直接赋值,末尾的 return 会自动返回它们。

命名返回值
package main
 
import "fmt"
 
func rect(w, h int) (area, perimeter int) {
    area = w * h
    perimeter = 2 * (w + h)
    return  // 裸 return,返回命名值
}
 
func main() {
    a, p := rect(3, 5)
    fmt.Println("面积:", a, "周长:", p)
}

4. defer 延迟调用

defer 把语句推迟到当前函数返回前执行,常用于释放资源。

defer 执行顺序
package main
 
import "fmt"
 
func main() {
    defer fmt.Println("A")
    defer fmt.Println("B")
    defer fmt.Println("C")
    fmt.Println("main 主体")
}
💡defer 栈是 LIFO

多个 defer 后注册先执行。这是因为 defer 实际压入栈中,函数返回时反向弹出。

5. 闭包

函数可以引用外部作用域的变量,形成闭包。

闭包计数器
package main
 
import "fmt"
 
func counter() func() int {
    n := 0
    return func() int {
        n++
        return n
    }
}
 
func main() {
    c := counter()
    fmt.Println(c())  // 1
    fmt.Println(c())  // 2
    fmt.Println(c())  // 3
 
    // 另一个独立的计数器
    c2 := counter()
    fmt.Println(c2()) // 1
}

6. 函数作为值

Go 中函数是一等公民,可以赋值给变量、作为参数传递。

函数作为参数
package main
 
import "fmt"
 
func apply(nums []int, f func(int) int) []int {
    out := make([]int, len(nums))
    for i, v := range nums {
        out[i] = f(v)
    }
    return out
}
 
func main() {
    sq := apply([]int{1, 2, 3, 4}, func(x int) int { return x * x })
    fmt.Println(sq)
 
    dbl := apply([]int{1, 2, 3, 4}, func(x int) int { return x * 2 })
    fmt.Println(dbl)
}

7. error 基础

Go 用 error 类型表示错误,惯例是最后一个返回值为 error。

基本 error
package main
 
import (
    "errors"
    "fmt"
)
 
func safeDiv(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("除数不能为 0")
    }
    return a / b, nil
}
 
func main() {
    if v, err := safeDiv(10, 2); err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Println("结果:", v)
    }
    if _, err := safeDiv(10, 0); err != nil {
        fmt.Println("错误:", err)
    }
}

🎯 练习

斐波那契
// 任务:实现一个返回前 n 个斐波那契数的函数
// fib(7) = [0, 1, 1, 2, 3, 5, 8]
 
package main
 
import "fmt"
 
func fib(n int) []int {
    // 补全代码
    return nil
}
 
func main() {
    fmt.Println(fib(7))
}

小结

  • ✅ func 定义函数,可返回多个值
  • ✅ 命名返回值 + 裸 return
  • ✅ defer 延迟调用(LIFO)
  • ✅ 闭包捕获外部变量
  • ✅ 函数是一等公民
  • ✅ error 是惯用的错误处理方式

下一章 数据结构:数组、切片、map。