附录 A 管的是「语法怎么写」,这一页管的是「某个活儿该找哪个包」。它按「想做什么 → 用哪个包哪个函数」组织,覆盖全书真正用到、以及日常最常翻的标准库 API。
表里的函数签名都在本机 go1.27.0 上用 go doc 核对过,不是凭记忆写的;省略号表示签名里与查询无关的部分。带版本标注的 API 低于该版本不可用。
字符串处理:strings
| 想做什么 | 函数签名 |
|---|---|
| 判断包含 / 前后缀 | func Contains(s, substr string) bool / HasPrefix / HasSuffix |
| 找位置 | func Index(s, substr string) int(找不到返回 -1) |
| 按分隔符切分 | func Split(s, sep string) []string / SplitN(s, sep string, n int) |
| 按空白切分 | func Fields(s string) []string |
| 连接 | func Join(elems []string, sep string) string |
| 替换 / 重复 | func ReplaceAll(s, old, new string) string / Repeat(s string, count int) |
| 去空白 / 前后缀 | func TrimSpace(s string) string / TrimPrefix / TrimSuffix |
| 一次切两半 | func Cut(s, sep string) (before, after string, found bool) |
| 高效拼接 | var b strings.Builder + b.WriteString(s) + b.String() |
strings 的函数都返回新串(string 不可变)。在循环里拼接大量字符串时,用 strings.Builder 而不是 +。
类型转换:strconv
| 想做什么 | 函数签名 |
|---|---|
| 字符串转整数 | func Atoi(s string) (int, error) |
| 整数转字符串 | func Itoa(i int) string |
| 按进制解析 | func ParseInt(s string, base int, bitSize int) (int64, error) |
| 解析浮点 / 布尔 | func ParseFloat(s string, bitSize int) (float64, error) / ParseBool(str string) (bool, error) |
| 格式化整数 / 浮点 | func FormatInt(i int64, base int) string / FormatFloat(f float64, fmt byte, prec, bitSize int) string |
| 加引号 / 去引号 | func Quote(s string) string / Unquote(s string) (string, error) |
Go 不会隐式转换数字与字符串,"1" + 1 直接编译失败;解析用 strconv,类型转换用 T(v)。
字节缓冲:bytes
| 想做什么 | 函数签名 |
|---|---|
| 读写缓冲 | var buf bytes.Buffer(实现 io.Reader / io.Writer) |
| 字节切片转 Reader | func NewReader(b []byte) *Reader |
| 包含 / 比较 | func Contains(b, subslice []byte) bool / Equal(a, b []byte) bool |
bytes.Buffer 与 strings.Builder 类似,但它面向 []byte,同时可读可写,常用来拼装 HTTP 请求体。
时间:time
| 想做什么 | 函数签名 |
|---|---|
| 当前时间 | func Now() Time |
| 构造时间 | func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time |
| 解析 / 格式化 | func Parse(layout, value string) (Time, error) / t.Format(layout) |
| 时长解析 | func ParseDuration(s string) (Duration, error) |
| 休眠 / 等待 | func Sleep(d Duration) / func After(d Duration) <-chan Time |
| 时间差 | func Since(t Time) Duration / t.Sub(u Time) Duration |
package main
import (
"fmt"
"time"
)
func main() {
t := time.Date(2026, 10, 9, 10, 0, 0, 0, time.UTC)
fmt.Println(t.Format(time.RFC3339))
d, _ := time.ParseDuration("1h30m")
fmt.Println(d.Minutes())
}
2026-10-09T10:00:00Z
90
布局字符串用的是「参考时间」2006-01-02 15:04:05,常量 time.RFC3339 最常用。判断时间是否为零值用 t.IsZero()。
JSON:encoding/json
| 想做什么 | 函数签名 |
|---|---|
| 序列化 / 反序列化 | func Marshal(v any) ([]byte, error) / Unmarshal(data []byte, v any) error |
| 带缩进序列化 | func MarshalIndent(v any, prefix, indent string) ([]byte, error) |
| 流式编解码 | func NewEncoder(w io.Writer) *Encoder / NewDecoder(r io.Reader) *Decoder |
| 原始 JSON | type RawMessage []byte |
结构体字段通过标签控制键名:ID int64 `json:"id"` ;omitempty 让零值字段被省略。json.Number 可避免大整数被转成 float64 丢精度。
文件与进程:os
| 想做什么 | 函数签名 |
|---|---|
| 读 / 写整个文件 | func ReadFile(name string) ([]byte, error) / WriteFile(name string, data []byte, perm FileMode) error |
| 打开 / 创建 | func Open(name string) (*File, error) / Create(name string) (*File, error) |
| 目录操作 | func MkdirAll(path string, perm FileMode) error / ReadDir(name string) ([]DirEntry, error) |
| 环境变量 | func Getenv(key string) string / LookupEnv(key string) (string, bool) |
| 命令行参数 | var Args []string(含程序名) |
| 退出进程 | func Exit(code int) |
| 标准流 | os.Stdin / os.Stdout / os.Stderr |
os.ReadFile / os.WriteFile 是最常用的文件读写入口;写文件权限常写 0o644,目录常写 0o755。
输入输出:io
| 想做什么 | 函数签名 |
|---|---|
| 读完所有内容 | func ReadAll(r Reader) ([]byte, error) |
| 拷贝 | func Copy(dst Writer, src Reader) (written int64, err error) / CopyN(dst Writer, src Reader, n int64) |
| 丢弃输出 | var Discard Writer(黑洞) |
| 读到指定长度 | func ReadFull(r Reader, buf []byte) (n int, err error) |
| 分流读取 | func TeeReader(r Reader, w Writer) Reader |
| 文件结束错误 | var EOF = errors.New("EOF") |
package main
import (
"io"
"os"
"strings"
)
func main() {
io.Copy(os.Stdout, strings.NewReader("hello\n"))
}
hello
读循环里判断结束,用 errors.Is(err, io.EOF) 而不是字符串比较。
格式化:fmt
| 想做什么 | 函数签名 |
|---|---|
| 格式化字符串 | func Sprintf(format string, a ...any) string |
| 构造错误 | func Errorf(format string, a ...any) error(%w 包装) |
| 打印 | func Println(a ...any) (n int, err error) / Printf(format string, a ...any) |
| 写入指定 Writer | func Fprintln(w io.Writer, a ...any) (n int, err error) |
常用动词:%v 默认、%+v 带字段名、%#v Go 语法、%T 类型、%q 加引号字符串、%d 整数、%s 字符串、%w 包装错误、%x 十六进制。
错误:errors
| 想做什么 | 函数签名 |
|---|---|
| 创建 / 包装 | func New(text string) error / fmt.Errorf("...: %w", err) |
| 判断类别 | func Is(err, target error) bool |
| 取回类型 | func As(err error, target any) bool |
| 解包 / 合并 | func Unwrap(err error) error / func Join(errs ...error) error |
errors.Is 沿错误链逐层比较,errors.As 逐层做类型匹配;两者都不要求你手动 Unwrap。
泛型容器:slices / maps / cmp
| 想做什么 | 函数签名 |
|---|---|
| 排序 | func Sort[S ~[]E, E cmp.Ordered](x S) / SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) |
| 查找 / 包含 | func Index[S ~[]E, E comparable](s S, v E) int / Contains |
| 复制 / 比较 | func Clone[S ~[]E, E any](s S) S / Equal[S ~[]E, E comparable](s1, s2 S) bool |
| 删除 / 插入 | func Delete[S ~[]E, E any](s S, i, j int) S / Insert[S ~[]E, E any](s S, i int, v ...E) S |
| map 取键 / 取值 | func Keys[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K] / Values |
| map 复制 / 比较 | func Clone[M ~map[K]V, K comparable, V any](m M) M / Equal |
| 通用比较 | func Compare[T Ordered](x, y T) int / func Or[T comparable](vals ...T) T |
package main
import (
"cmp"
"fmt"
"maps"
"slices"
)
func main() {
xs := []int{3, 1, 2}
slices.Sort(xs)
slices.SortFunc(xs, func(a, b int) int { return cmp.Compare(b, a) })
m := map[string]int{"b": 2, "a": 1}
fmt.Println(xs, slices.Sorted(maps.Keys(m)))
fmt.Println(cmp.Or("", "fallback"))
}
[3 2 1] [a b]
fallback
slices / maps 是 1.21 起提供的泛型标准库,优先于手写循环与 sort.Slice。maps.Keys / slices.Sorted 是 1.23 起的迭代器风格 API。
同步:sync / sync/atomic
| 想做什么 | 类型 / 函数 |
|---|---|
| 互斥锁 / 读写锁 | type Mutex struct / type RWMutex struct |
| 等待一组完成 | type WaitGroup struct(Add / Done / Wait) |
| 只执行一次 | type Once struct(once.Do(f)) |
| 并发安全 map | type Map struct(Load / Store / Delete) |
| 原子整数 | type atomic.Int64 struct(Add / Load / Store) |
| 原子函数 | func atomic.AddInt64(addr *int64, delta int64) int64 |
Mutex 保护一段临界区,atomic 适合单个计数器的自增,sync.Map 只在读多写少、键集合稳定的场景才优于「Mutex + 普通 map」。
上下文:context
| 想做什么 | 函数签名 |
|---|---|
| 根 context | func Background() Context / TODO() |
| 可取消 | func WithCancel(parent Context) (ctx Context, cancel CancelFunc) |
| 带超时 / 截止 | func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) / WithDeadline |
| 携带值 | func WithValue(parent Context, key, val any) Context |
| 查询原因 | func Cause(c Context) error |
context 是函数第一个参数、命名约定为 ctx,不要把它塞进结构体。cancel 函数一定要 defer 调用,否则会泄漏。
HTTP 服务端:net/http
| 想做什么 | 函数 / 类型 |
|---|---|
| 注册路由 | func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) |
| 新建多路复用器 | func NewServeMux() *ServeMux(支持 "GET /tasks/{id}" 模式,1.22+) |
| 取路径参数 | func (r *Request) PathValue(name string) string |
| 启动服务 | func ListenAndServe(addr string, handler Handler) error |
| 优雅关闭 | func (s *Server) Shutdown(ctx context.Context) error |
| 发起请求 | func Get(url string) (resp *Response, err error) / Post |
路由模式里的 {id} 是 1.22 起的增强,r.PathValue("id") 取出对应段;方法前缀(GET )也由这套机制解析。
结构化日志:log/slog
| 想做什么 | 函数签名 |
|---|---|
| 新建 logger | func New(h Handler) *Logger |
| JSON / 文本 handler | func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler / NewTextHandler |
| 记录日志 | func (l *Logger) Info(msg string, args ...any) / Error / Debug |
| 绑定固定字段 | func (l *Logger) With(args ...any) *Logger |
| 构造字段 | func String(key, value string) Attr / Int / Bool / Any |
| 分组 | func Group(key string, args ...any) Attr |
package main
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.With("service", "taskapi").Info("started", "port", 8080)
}
{"time":"...","level":"INFO","msg":"started","service":"taskapi","port":8080}
slog 是 1.21 起的结构化日志标准库,输出是可被日志系统解析的键值对,优于 fmt.Println 式打印。
排序与数学:sort / math
| 想做什么 | 函数签名 |
|---|---|
| 自定义排序 | func Slice(x any, less func(i, j int) bool) / SliceStable |
| 二分查找 | func Search(n int, f func(int) bool) int |
| 浮点最值 / 绝对值 | func Max(x, y float64) float64 / Min / Abs |
| 幂 / 平方根 / 取整 | func Pow(x, y float64) float64 / Sqrt(x float64) float64 / Round |
新代码优先用泛型的 slices.Sort / slices.SortFunc(类型安全),sort.Slice 保留给需要自定义比较、又不便引入泛型的旧代码。
小结
- 字符串用
strings,拼接多时用strings.Builder;数字与字符串互转用strconv。 - 时间用
time,布局字符串是参考时间2006-01-02 15:04:05,超时用Duration。 - JSON 用
encoding/json,字段标签控制键名;流式处理用Encoder/Decoder。 - 文件用
os.ReadFile/WriteFile,通用 I/O 用io.Copy/ReadAll,结束判断用errors.Is(err, io.EOF)。 - 错误用
errors.New创建、fmt.Errorf+%w包装、errors.Is/As判定。 - 泛型容器优先用
slices/maps/cmp,它们比手写循环更安全也更简洁。 - 并发安全用
sync与sync/atomic;跨调用传递取消与超时用context。 - 服务端用
net/http(1.22+ 路由模式),日志用log/slog输出结构化字段。
标准库足够大,不可能在这里穷尽。真正该记住的不是每个函数的名字,而是「这类需求大概归哪个包管」——想清楚这一点,去 go doc 里翻具体签名就是几分钟的事。附录 C 会继续整理 go 命令与工具链。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。