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 的容量。理解 len 和 cap 的区别是写高性能 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)
💬 评论 0
还没有评论,快来抢沙发吧~