Go
一、为什么是 Go
Go 由 Rob Pike、Ken Thompson 等人在 Google 设计,2009 年开源。诞生背景:C++ 编译慢、Java 启动慢、Python 性能差,Google 内部需要一门”既能写系统又能写服务”的语言。
它做对了几件事:
- 极简语法:关键字只有 25 个,几小时上手
- 原生并发:
go func()一行起协程,channel 解决通信 - 静态编译 + 单二进制:部署只丢一个文件,不带运行时依赖
- GC 但够快:低延迟 GC(< 1ms STW)
- 强大的标准库:HTTP / JSON / 加密 / 模板全自带
代价:泛型直到 1.18 才有,错误处理啰嗦(if err != nil 满屏),没有继承。
适合:网络服务、CLI 工具、云基础设施、并发处理。
不适合:CPU 密集科学计算(不如 C++/Rust)、桌面 GUI(生态弱)。
二、Hello World
1 | package main |
1 | go run main.go # 直接跑 |
三、核心语法速览
1 | // 变量 |
四、Goroutine + Channel
1 | package main |
go 关键字 + channel 让”生产者-消费者”模型变成几行代码。Don’t communicate by sharing memory; share memory by communicating.
五、模块(Go Modules)
1 | go mod init github.com/me/myapp # 初始化 |
go.mod 声明依赖版本,go.sum 锁哈希。
六、标准库 HTTP 服务
1 | package main |
不依赖任何框架,标准库就能写生产级 HTTP 服务。
七、踩坑笔记
| 坑 | 现象 | 解法 |
|---|---|---|
| goroutine 泄露 | 起了不会退出 | channel 关闭时 worker 要 return;用 context.Context 控生命周期 |
| for-range 闭包变量 | goroutine 拿到的都是最后一个 | Go 1.22 已修;老版本要 i := i 拷贝 |
| map 并发读写 panic | “concurrent map writes” | 用 sync.Map 或加 sync.Mutex |
| interface 判 nil | 明明赋了 nil 还不等于 nil | interface 内部是 (type, value),type 不为空就不等于 nil |
| defer 在循环里 | 文件句柄不释放 | 把循环体抽成函数;或用 defer file.Close() 后立即处理 |
| GOPATH vs Module | 老代码混乱 | 一律用 Go Modules(1.16+ 默认),告别 GOPATH |
八、生态推荐
| 类型 | 推荐 |
|---|---|
| Web 框架 | Gin、Echo、Fiber |
| ORM | GORM、ent、sqlx |
| 微服务 | go-zero、Kratos、go-kit |
| CLI | cobra、urfave/cli |
| 配置 | viper |
参考
- 官网:https://go.dev
- Go by Example:https://gobyexample.com
- Go 圣经(中文):https://gopl-zh.github.io
- Effective Go:https://go.dev/doc/effective_go
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Michael's Blog!
评论



