总结一下最近使用 golang 写了几个简单的工具和项目的初体验。总体感觉 golang 在语法设计上面非常糟糕,不喜欢,但是在运行时和标准库上面,确实解决了之前编程语言的很多痛点,所以目前 golang 在业务项目蚕食 Java 的地盘。但是 JVM + Kotlin 还是目前最好的业务技术栈,如果不需要计算性能的话,有了 typing 提示后 web 项目用 Python 也是很好的选择,千万不要信了 golang 那些不需要 ORM/使用标准库就够了/显式处理error才是最佳实践的鬼话。
好的方面
工具链非常完善好用
虽然 maven 也有根据模板创建初始化项目的命令,但是那个命令长的根本没人记得住,所以才有 https://start.spring.io/ 这种网站,npm、cargo、uv 这种交互命令行才是人道主义,golang 在命令行方面做的非常好,go mod go tidy 等体验并没有比 cargo 差多少,当然目前接触的项目都非常简单。
标准库非常丰富
除了 python,golang 的标准库应该是最丰富的。甚至连 http 库都是自带的,在简单的命令工具场景(devops)场景下,golang 几乎可以取代 python 成为脚本运维工具,这也是很多运维 boy 转到 golang 的条件,毕竟运维环境大概率有 golang 标准库但是不能安装第三方库。
交叉编译比较简单
写了一个上传 log 到 s3 的小工具,需要编程成二进制集成到 java 项目中一块部署,开发环境是 windows,部署环境是 linux,golang 一行命令就解决了,使用 rust 没能实现 win 交叉编译到 linux,主要是 windows 需要安装的东西太多了,开发电脑不允许,在个人电脑试了一下也可以。当然使用 python 也能解决,但是体积非常大,超过了 5M 允许的限制。
编译非常快
得益于 golang 的语法简单,没有 meta programming, 所以编译非常快,可以说编译+启动一个 golang 项目和启动 python 小项目几乎一样快,这在 Java 项目上都是难以想象的,大部分使用 Java boy 都需要使用破解版的 JRebel 热更新解决启动慢的问题。
启动快,初始内存小
启动内存其实对于企业 web 开发不算什么太大问题。但是对于个人项目,流量非常小的服务还是很大的优势。毕竟几百兆内存也是需要还钱的。
缺点
项目写到一半我就感觉有点恶心了,可能是用过 python 和 scala 的原因,golang 的语法感觉就是半成品,连 Java 都比他严谨一点。
错误处理
golang 的错误处理有两个问题,一是繁琐,整个代码充斥的 if err != nil {},美其名曰在错误发生的地方处理错误,但是又允许通过 r, _=fn() 省略 err,这个本质上是奖励偷懒者。二是 error 是值,导致传递的信息非常有限,底层 fmt.Errorf + %w 其实是一个 error string 错误链,然后使用 error.Is 判断处理,对于 java 过来的人,没有 stack trace 而 err 只是一个 string 真的非常不习惯,感觉上了生产仅靠一行 error string 定位错误非常困难吧,虽然我还没遇到生产问题。
空值设计
这个问题其实比错误处理还搞笑,一个int你无法判断是nil还是0。还有感觉 golang 的 json 序列化就是玩的,也不知道 golang web 开发前后端是怎么约定空值的,前端还需要额外约定的 json 明显属于 json 包设计有 bug 就这么用了十几年。当然 1.24 的 omitzero
可以解决一部分问题。JSON 包新提案:用“omitzero”解决编码中的空值困局
其他
time 格式、for-range 这些就不吐槽了,官方也在不停修复,但是感觉 golang 和 golang 那些项目都是发版跟玩似的(说的就是 hugo 你),严肃语言怎么也不会把 omitepmty
不支持 time 这种东西发布出来吧,把工作甩给前端开发么?
设计问题
- Context 和其他语言的 ThreadLocal/contextvars 相比,真的太丑了,整个方法链被强制污染了,但是个人还能接收,至少满足显示易懂这个点。
- slice 对于新人总是会踩坑,更多还是设计者的问题,不是初学者的问题。
- 没有默认参数,没有 computed property, 没有 set,queue 等标准库,在业务场景这些都是非常有用且高频的工具。
- 几乎所有的文件都是在文件根目录下面,_test.go 和源码相邻,很快就导致项目文件管理非常混乱。
- channel 看上去非常简单方便,实际使用的时候非常容易发生数据竞争。uber 专门写过
- panic处理不当会炸应用,java的绝大所数异常不影响整个应用。
- go mod的机制导致你fork代码库后想改一点东西测试需要替换仓库代码所有路径名。。。没见过比这更傻了
What “sucks” about Golang? : r/golang
Go 错误陷阱 — Go Traps
GoLangBooks/50 Shades of Go Traps GotchasandCommonMistakesforNewGolangDevs.pdf at master · diptomondal007/GoLangBooks
Golang Sucks - Home
I don’t like Golang – Martin Vysny – First Principles Thinking
Golang Sucks | Hacker News — Golang Sucks | Hacker News
Discover the Dark Side of Go: Why This Popular Language May Sucks | by Roma Gordeev | Medium
ksimka/go-is-not-good: A curated list of articles complaining that go (golang) isn’t good enough
Golang is not a good language
Lies we tell ourselves to keep using Golang
My reflections on Golang - DEV Community
Why Go Is Not Good :: Will Yager