Go 语言共有 15个内置函数(builtin),无需 import 即可直接使用。下面分类详细介绍:

切片 / 数组操作

len(v) — 万能长度函数,适用于 string(返回字节数)、array、slice、map、channel。

s := []int{1, 2, 3}
fmt.Println(len(s))       // 3

m := map[string]int{"a": 1}
fmt.Println(len(m))       // 1

str := "Hello, 世界"
fmt.Println(len(str))     // 13 (字节数, 非字符数)

cap(v) — 获取 slice 或 channel 的容量。理解 lencap 的区别是写高性能 Go 代码的基础:len 是当前元素数,cap 是底层数组可容纳的最大元素数。

s := make([]int, 3, 10)
fmt.Println(len(s), cap(s)) // 3 10

s2 := s[1:3]
fmt.Println(len(s2), cap(s2)) // 2 9

append(slice, elems...) — 切片追加元素的核心函数。扩容策略:容量不足时自动翻倍(大切片逐步缩小倍率)。注意:必须接收返回值,因为可能返回指向新数组的全新切片。

s := []int{1, 2}
s = append(s, 3, 4)      // [1 2 3 4]

// 合并两个切片 (用 ... 展开)
t := []int{5, 6}
s = append(s, t...)      // [1 2 3 4 5 6]

// append 字节到字符串
b := []byte("Hello")
b = append(b, " Go"...)  // Hello Go

copy(dst, src) — 安全地在两个切片之间复制数据,不会越界,返回实际复制数量。也支持 copy(byteSlice, string)

src := []int{1, 2, 3, 4, 5}
dst := make([]int, 3)
n := copy(dst, src)
// dst=[1 2 3], n=3

// 复制字符串到字节切片
b := make([]byte, 5)
copy(b, "Hello")
// b=[72 101 108 108 111]

映射操作

delete(m, key) — 删除 map 中的键,key 不存在时静默忽略。Go 1.21+ 可用 clear(m) 一次性清空整个 map。

m := map[string]int{
    "a": 1, "b": 2, "c": 3,
}
delete(m, "b")
// m = {"a": 1, "c": 3}

delete(m, "notExist") // 不会 panic

clear(t)(Go 1.21+)— 清空 map 所有键值对,或将 slice 所有元素置零(长度不变)。

m := map[string]int{"a": 1, "b": 2}
clear(m)
fmt.Println(len(m)) // 0

s := []int{1, 2, 3, 4}
clear(s)
fmt.Println(s)      // [0 0 0 0]
fmt.Println(len(s)) // 4 (长度不变)

内存分配

make(T, args...) — 专门用于初始化 slice、map、channel 三种引用类型,返回已初始化的值(不是指针)。

// 切片: make([]T, len, cap)
s := make([]int, 5, 10)

// 映射: make(map[K]V, hint)
m := make(map[string]int, 100)

// 通道: make(chan T, bufSize)
ch := make(chan int, 5)     // 缓冲通道
uch := make(chan string)     // 无缓冲通道

new(T) — 分配任意类型的零值内存,返回指针 *T。实际代码中 &T{} 更常用。

p := new(int)
fmt.Println(*p)  // 0
*p = 42
fmt.Println(*p)  // 42

// 等价写法 (更常见)
p2 := &struct{ X int }{}

通道操作

close(ch) — 关闭通道,告知接收方数据已发送完毕。只能由发送方调用,重复关闭或向已关闭通道发送数据均会 panic。

ch := make(chan int, 3)
ch <- 1; ch <- 2; ch <- 3
close(ch)

// range 会在 close 后自动退出
for v := range ch {
    fmt.Println(v) // 1, 2, 3
}

// 检查通道是否关闭
v, ok := <-ch
// ok=false 表示通道已关闭且为空

错误 / 控制流

panic(v) — 触发运行时恐慌,逐层执行 defer 后崩溃。用于不可恢复的错误,普通错误务必返回 error

func divide(a, b int) int {
    if b == 0 {
        panic("除数不能为零")
    }
    return a / b
}

// 一般只在「不可恢复的错误」时使用
// 业务代码优先返回 error

recover() — 在 defer 函数中捕获 panic,实现类似 try-catch 的效果,是编写健壮中间件的关键。

func safeDiv(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("捕获到 panic: %v", r)
        }
    }()
    return a / b, nil
}

result, err := safeDiv(10, 0)
// err="捕获到 panic: runtime error: ..."

数值 / 复数

complex(r, i) / real(c) / imag(c) — 构建和拆解复数,常用于 FFT、信号处理等场景。

c := complex(3.0, 4.0) // 3+4i
fmt.Println(real(c)) // 3
fmt.Println(imag(c)) // 4

// 计算模长
import "math"
mod := math.Sqrt(real(c)*real(c) + imag(c)*imag(c))
fmt.Println(mod) // 5

min(x, y, ...) / max(x, y, ...)(Go 1.21+)— 内置的多参数最值函数,终于不用手写比较逻辑了。

fmt.Println(min(3, 1, 4, 1, 5)) // 1
fmt.Println(max(3, 1, 4, 1, 5)) // 5
fmt.Println(min("apple", "banana")) // "apple"

// 切片中的元素需手动处理
s := []int{3, 1, 4}
m := s[0]
for _, v := range s[1:] { m = min(m, v) }

调试输出

print() / println() — 输出到 stderr,仅用于简单调试。生产代码请始终使用 fmt,功能更完整,输出到 stdout,且格式可控。

print("debug: ")
println("value =", 42)

// 推荐用 fmt 包替代
import "fmt"
fmt.Println("value =", 42)  // 输出到 stdout
fmt.Fprintf(os.Stderr, "err: %v", err)