写第一个 Go 程序,只需要一个命令行工具、一个 go.mod 文件和一个名为 main 的包。本文讲清 go run、go build、gofmt 和 go vet 各自做什么,以及 Go 为什么拒绝编译带有未使用导入的代码。
Go 的每个变量都从零值开始,数字从不自动转换类型,常量比变量更灵活。本文讲解 var、:=、定长整数、溢出、iota,以及用来查看值的 Printf 格式动词。
Go 的流程控制只靠 if、唯一的循环关键字 for,以及默认不贯穿的 switch。本文讲解每种写法、Go 1.22 让每次迭代拥有独立循环变量的改动,以及带标签的 break。
Go 函数可以返回多个值,可以作为闭包带着变量走,还能用 defer 安排清理工作。本文逐一讲解,包括延迟调用的执行顺序,以及参数在什么时候确定。
Go 切片是一扇小窗口,背后的数组才真正存放数据。看清这扇窗口,len、cap、append,以及两个切片互相修改的 bug 就不再神秘。
Go 的 map 按键存值,靠哈希来查找。弄清读取不存在的键为什么得到零值,写入 nil map 为什么会 panic,遍历顺序为什么每次运行都不一样。
Go 字符串是只读的字节序列,通常是 UTF-8。看清这一点,len 数的是字节、索引得到字节、range 得到 rune、切片会把一个字符切成两半,就都说得通了。
Go 接口是一组方法,任何拥有这些方法的类型都自动满足它,不用声明。讲清方法集、Stringer、io.Reader、类型选择,以及为什么装着 nil 指针的 error 不是 nil。
Go 的错误是普通的值,返回之后由你检查。学会给错误包装上下文,用 errors.Is 和 errors.As 找到根因,一次合并多个错误,并把 panic 和 recover 留给真正的 bug。
值放在栈上还是堆上,Go 替你决定。本文讲逃逸分析怎样做这个决定,怎样用 go build -gcflags=-m 查看它,怎样统计分配次数,以及垃圾回收器随后做什么。
goroutine 是和程序其余部分同时运行的函数,Go 可以同时跑成千上万个。学会启动它、等待它、避免泄漏,并看懂调度器怎样让少数线程承载它们。
Go 通道在 goroutine 之间传递值,也让它们互相等待。本文讲无缓冲和有缓冲通道、关闭、死锁、nil 通道,以及 select 如何同时等待多个通道。
两个 goroutine 不加协调地修改同一个变量,就会产生数据竞争,悄悄丢失更新。学会用 sync.Mutex、RWMutex、atomic 和 Once 避免它,再用 go run -race 把它找出来。
Go 的 context 告诉处理同一项任务的每个 goroutine 什么时候该停。本文先讲取消、超时和请求作用域的值,再用它们搭建不会泄漏的工作池、管道、扇出扇入、errgroup 和信号量。
Go 标准库自带能上生产的 HTTP 服务器。学习处理器、用 ServeMux 的方法和路径模式做路由、ResponseWriter 的规则、每个请求经历了什么,以及 http.Server 为什么要设超时。
不用任何第三方包,用 Go 搭建一个任务列表 REST API。逐层实现存储、路由、安全的 JSON 解码、校验、状态码、中间件和 slog 日志。
用 httptest、假存储、日志断言、竞态检测器和模糊测试来测 Go REST API,再靠服务器超时、优雅关闭和一个静态二进制文件把它发布出去。