Gin 真的是“真菌”吗?—— 一篇引发热议的“反 Gin”檄文解读

大家好,我是Tony Bai。

“Gin 就像是一种伪装成软件库的阴险真菌:它很容易感染,一旦沾上就几乎无法去除,除非你极其小心,否则还会传染给你的朋友。”

2025 年 12 月,Efron Licht 发布了一篇名为《Gin 是一个非常糟糕的软件库》的长文,用词之激烈、抨击之全面,瞬间引爆了 Go 社区。他将 Gin 比作“真菌”,并列举了从代码膨胀到 API 设计混乱的种种“罪状”。

这篇文章虽然充满了情绪化的发泄,但它同时也触及了许多资深 Gopher 心照不宣的痛点。Reddit 上的热烈讨论证明了这一点:虽然很多人不喜欢作者的语气,但绝大多数人承认他的技术批评是站得住脚的

今天,让我们剥离情绪,结合社区的反馈,深入剖析这篇檄文背后的技术逻辑:作为 Go 生态中最流行的 Web 框架,Gin 真的有那么不堪吗?

第一宗罪:惊人的代码膨胀 (Code Bloat)

作者首先指出的,是 Gin 与其解决的问题之间巨大的比例失调

  • 标准库 net/http:仅用 2.5 万行 代码就实现了完整的 HTTP 协议栈(包含客户端、服务端、TLS 等)。

  • Gin:为了实现路由和中间件等相对简单的功能,其依赖树竟然引入了 87 万行 代码和 55MB 的体积!

更令人咋舌的是,Gin 的依赖树中包含了至少 6 个不同的 JSON 库(包括 sonicgo-jsonugorji/go/codec 等)。一名Reddit 用户 证实了这一点,并指出即使在不使用 msgpack 的情况下,Gin 也会引入巨大的二进制开销。虽然可以通过 -tags nomsgpack 来缓解,但这并非默认行为。

这种“把厨房水槽都装进去”的依赖管理方式,对于追求简洁和二进制体积的 Go 项目来说,确实是一个沉重的负担。

第二宗罪:混乱的 API 设计与“抽象泄漏”

作者对 Gin 的 API 设计进行了无情的嘲讽,称其“表面积像工业散热器一样大,而且一样吸热(sucks)”。

  • gin.Context 的过度设计:这个核心结构体拥有超过 133 个方法!它混杂了请求参数解析、响应写入、内容协商、Cookie 处理甚至 HTML 模板渲染等所有功能。一位Reddit 用户评论道:“Gin 就是当每一个可能的使用场景都塞进同一个库时发生的事情。”

  • 奇怪的方法签名:相比标准库清晰的接口,Gin 提供了数十种获取参数的方法,甚至还有 BindYAMLBindTOML 等特定的绑定方法。这种设计不仅增加了学习成本,也让代码的可测试性大打折扣。

第三宗罪:致命的“锁定效应” (Lock-in)

这是作者认为最严重的问题,也是将其比作“真菌”的核心原因。

  • 单向兼容性:你可以很容易地将一个标准的 http.Handler 包装成 Gin 的 handler。

  • 无法逃离:但如果你想从 Gin 迁移回标准库,或者是迁移到其他框架(如 Chi, Echo),你会发现几乎不可能。因为你的业务逻辑已经深度耦合了 *gin.Context 中那 100 多个特有的方法。

正如 一位Reddit 用户所言:“如果你想不付出巨大的开发者纪律和克制,就在 Go 中实现‘按需付费’(只引入需要的依赖),那几乎是不可能的。Gin 让事情变得简单,所以人们就用了它,尽管方式很糟糕。”

社区声音:不仅是批评,更是反思

Reddit 上的讨论为这场批判提供了更多元的视角:

  1. “标准库至上”派的胜利:许多用户表示,他们早已放弃 Gin,转而投向 Echo 或 Chi。Chi 因为其极简的设计(仅 1000 多行代码)和对标准库接口的严格遵守,被多次点名表扬。

  2. 对“中间件地狱”的共鸣:一名用户指出,虽然标准库很美,但它的中间件链和上下文处理确实不如框架方便。Gin 的成功在于它填补了标准库在人体工程学 (Ergonomics) 上的空白,尽管是以一种臃肿的方式。

  3. 初学者的陷阱:多位用户提到,AI(如 ChatGPT)往往会默认推荐 Gin 给新手,导致许多内部服务和 API 仅仅因为“AI 推荐”就染上了这种“真菌”。这加剧了 Gin 的锁定效应。

小结:我们还需要 Gin 吗?

Efron Licht 的批评固然犀利,但也存在幸存者偏差。对于初学者或快速原型开发来说,Gin 提供的“一站式”体验(路由、参数绑定、验证、JSON 序列化)确实极大地降低了门槛。

然而,随着 Go 标准库的不断进化(特别是 Go 1.22 引入了增强的 http.ServeMux),以及像 Chi 这样更轻量且优秀的替代品的成熟,原生开发的体验已经今非昔比

给 Go 开发者的一些建议:

  1. 对于新项目:建议评估 标准库 + Chi 或 Echo。它们提供了更好的模块化和更小的依赖负担。

  2. 对于已使用 Gin 的项目:不要恐慌,但要警惕。在编写 handler 时,尽量将 *gin.Context 限制在最外层,将业务逻辑抽离到与框架无关的 Service 层中。

  3. 警惕“便利性”陷阱:在引入任何“全家桶”框架之前,问自己一个问题:我引入的这 55MB 依赖,真的只是为了少写几行 if err != nil 吗?

Go 的哲学是“少即是多”。Gin 在某种程度上,是对这一哲学的背离。这篇文章虽然激进,但它是一记警钟,提醒我们在享受便利的同时,不要忘记了软件工程中那些关于复杂性、依赖管理和可维护性的永恒真理。

资料链接:

  • https://eblog.fly.dev/ginbad.html

  • https://www.reddit.com/r/golang/comments/1pifcca/gin_is_a_very_bad_software_library/


如果本文对你有所帮助,请帮忙点赞、推荐和转发

点击下面标题,阅读更多干货!

-  Go 模块构建与依赖管理:我们到底在“折腾”什么?

拒绝“面条代码”,做有架构思维的 Go API 设计师

Go 也开始“叛逆”了?深度解读 JetBrains 2025 报告:为何“原生信仰”不再是唯一答案

“简单”不是“容易”:Go开发者应该懂的5个道理

Go json/v2实战:告别内存爆炸,掌握真流式Marshal和Unmarshal

context:Go 语言的“天问”,你真的懂了吗?

Go社区的“轻框架”理念:自由的馈赠还是无形的枷锁?


🚀 原「Gopher部落」已重装升级为「Go & AI 精进营」知识星球,快来加入星球,开启你的技术跃迁之旅吧!

我们致力于打造一个高品质的 Go 语言深度学习 与 AI 应用探索 平台。在这里,你将获得:

  • 体系化 Go 核心进阶内容: 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏,夯实你的 Go 内功。

  • 前沿 Go+AI 实战赋能: 紧跟时代步伐,学习「Go+AI应用实战」、「Agent开发实战课」,掌握 AI 时代新技能。

  • 星主 Tony Bai 亲自答疑: 遇到难题?星主第一时间为你深度解析,扫清学习障碍。

  • 高活跃 Gopher 交流圈: 与众多优秀 Gopher 分享心得、讨论技术,碰撞思想火花。

  • 独家资源与内容首发: 技术文章、课程更新、精选资源,第一时间触达。

衷心希望「Go & AI 精进营」能成为你学习、进步、交流的港湾。让我们在此相聚,享受技术精进的快乐!欢迎你的加入!👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值