Corrode 这篇《Migrating from Go to Rust》,最值得看的地方,不是“Rust 又来挑战 Go”。

反而是它没有急着踩 Go。作者承认,Go 在后端仍然很强:静态二进制、网络标准库、gRPC、数据库生态、工具链,都成熟。大多数服务用 Go 写,够快,够稳,也够便宜。

真正的反常点在另一处:这篇指南关心的不是 benchmark,而是生产里的 nil panic、数据竞争、错误上下文丢失、P99 延迟尾部。这些问题到底该靠人记住,还是靠语言不让你忘。

Go 和 Rust 的分水岭,不在跑分

作者 Matthias Endler 先把立场摊开:他不喜欢 Go,认为 Go 把“容易”误当成“简单”;他也经营 Rust 咨询业务,Rust 被更多团队采用,对他有利。

这点要先放在桌面上。它不是中立白皮书,是一份带立场的迁移建议。但披露偏见,比伪装客观干净。

两门语言真正的分歧,不是“谁更先进”。而是风险放在哪里。

问题Go 常见做法Rust 常见做法现实差异
空值nil 检查、lint、团队约定Option<T> 强制处理 NoneGo 靠人别漏,Rust 让漏处理更难通过编译
错误if err != nil、手动包装上下文Result<T, E>、?、匹配Go 简洁直接,但错误语义容易散;Rust 更啰嗦,也更显式
数据竞争-race 运行时检测,依赖测试覆盖Send/Sync 编译期约束-race 有用,但没跑到的路径发现不了
资源生命周期GC 和约定兜底所有权、借用、RAIIGo 开发顺,Rust 前期卡,但生命周期更早暴露
延迟尾部GC 已经很强,但仍有分配和暂停成本无 GC,热路径可控Rust 不必然更快,但在高分配和 P99 敏感场景更有优势

这张表不能读成 Rust 全面碾压 Go。那是偷懒。

Go 的成功,恰恰来自它把复杂度压低。上手快,部署轻,工具链统一,团队协作成本低。Rob Pike 说过,gofmt 的风格不是任何人的最爱,却是所有人的最爱。意思很朴素:别把时间浪费在无谓争论上。

Go 和 Rust 都相信工具链。区别是,Go 主要用工具链减少协作摩擦;Rust 还试图用类型系统减少事故入口。

受影响的不是语言粉丝,是维护长期服务的人

这篇指南最该被谁看?不是想吵 Go 和 Rust 谁赢的人。

第一类,是正在维护 Go 后端服务、已经被线上稳定性问题磨过的工程团队。你们要做的不是把服务一夜之间改成 Rust,而是先盘点事故类型:nil panic 多不多,错误上下文是不是经常丢,并发共享状态是不是靠口头纪律,P99 延迟是不是被分配和 GC 放大。

如果这些问题很少,迁移收益就未必覆盖成本。继续用 Go,把 lint、errcheck、staticcheck、nilaway、-race、context 规范补齐,可能更划算。

如果这些问题反复出现,Rust 才开始有现实意义。它不是魔法,是把一部分线上排雷,改成编译期付款。

第二类,是技术负责人。你要关心的不是“Rust 工程师酷不酷”,而是账怎么结。

决策问题更偏向继续 Go更偏向评估 Rust
服务类型CRUD、内部 API、普通网络服务高并发核心链路、基础设施组件、延迟敏感服务
团队现状Go 熟练,事故少,交付压力大线上 bug 成本高,长期维护压力重
风险来源业务变化快,性能不是瓶颈并发安全、资源控制、错误模型经常出问题
迁移方式强化工具和规范从边界模块、性能热点、可靠性要求高的组件试点
最大代价继续依赖纪律学习曲线、编译时间、异步心智负担、招聘成本

这里的关键词是“试点”,不是“重写”。

如果一个团队连错误类型、超时策略、日志上下文都没有统一,直接迁 Rust 很可能只是把混乱换一种语法。Rust 会放大工程纪律,也会暴露组织问题。编译器能拦住很多 bug,拦不住需求乱飞、边界不清和抽象失控。

迁移值不值,看你愿不愿用学习成本换确定性

我不太买账“Rust 适合所有后端”的说法。很多服务用 Go 就很好。招人更容易,编译更快,生态更熟,排障资料也多。

但我也不买账“Go 已经足够,所以 Rust 没必要”。这话只对一部分团队成立。

问题不在语言信仰,而在事故价格。

一个 nil 在罕见路径触发 panic,单看代码只是少了一行判断。放到生产里,可能就是一次半夜告警。一个 map 被两个 goroutine 改写,测试没覆盖到,流量一上来才炸。一个错误被 return,却没带上下文,排障只能靠猜。

Go 不是没有办法。-race 很有价值,不能轻飘飘说它没用。它的问题是运行时检测,只能发现被执行过的路径。lint 和规范也有用,但前提是团队持续执行。

Rust 的态度更硬:Option 没处理,别当值用;Result 没处理,别装没事;跨线程共享可变状态,先过 Send/Sync。你可以嫌它烦,但它确实把一批事故提前变成编译错误。

延迟也是同一逻辑。Go 的 GC 已经很强,低暂停、并发、足够适合常见服务。Rust 无 GC 不等于天然更快。它的优势更具体:高分配压力、热路径控制、P99 尾延迟敏感时,Rust 更容易把不确定性压下去。

这里有一点历史回声。早年的铁路、电力、报业,扩张到一定规模后,真正的竞争不再只是“谁铺得快”,而是谁能把标准、调度、维护和事故责任固定下来。技术系统越大,纪律越贵。

Go 的纪律成本低,所以它赢了很多后端场景。Rust 的纪律成本前置,所以它适合那些不想把错误留到凌晨两点再结算的地方。

接下来最该观察的变量,不是又有多少团队宣布“全面拥抱 Rust”。那种口号没多少信息量。

更该看三件事:

  • Go 团队的事故复盘里,nil、数据竞争、错误上下文、尾延迟是否反复出现;
  • Rust 试点是不是能落在清晰边界上,而不是把整个系统推倒重来;
  • 团队能不能承担 Rust 的学习曲线、编译等待、异步复杂度和招聘成本。

“天下熙熙,皆为利来。”技术迁移也一样。Rust 给的利,不是漂亮跑分,而是更高的确定性。只是这笔利,不会免费到账。