Go 语言真的有这么破烂不堪吗

2024-08-14 17:25:41 +08:00
 jlak
前言:
第一次认识 Go 在十几年前了,当时玩着 Python
从那时候印象(没看过代码)里就一直非常好
感觉速度又快又简单
直到最近才开始上手,体验是简单到超乎我的意料
然后感觉深刻的错误判断非常非常的繁琐
几乎每个函数里需要写多个 err!=nil
对于我这种只会写写简单代码的 err!nil 有时超过业务逻辑
但这好处也很大 几乎将所有错误都归到了可视范围

正题:
自从开始正式关注之后,知乎 App 就开始推送大量的 Go 问题的回答(我没有在知乎上关注,应该是根据大数据)
其中绝大部分都是喷 Go 的
而且这个量非常的大 每天都会收到多篇
范围涵盖了 Go 的方方面面
这个量远远超过了我同样关注的 JS/Node
一开始不当回事 但是每天这么多推送
不禁让人重视这个问题
18665 次点击
所在节点    Go 编程语言
125 条回复
CynicalRose
2024-08-15 08:33:09 +08:00
soyo (即答
wssy001
2024-08-15 08:36:19 +08:00
google 的技能树全点在如何提升 AOT 编译速度上了,当初创造 golang 不就是为了加快项目编译
golang 只是 C 的网络语法糖,C 不擅长的,golang 也不擅长
yangzzz
2024-08-15 08:47:21 +08:00
@Ipsum 哈哈哈,我最近在接触 python 的 django 框架。去 github 上拉了一个别人写的项目,里面很多东西真的不写注释我也看不懂
voidmnwzp
2024-08-15 09:03:02 +08:00
因为它简单
layxy
2024-08-15 09:06:18 +08:00
Go 语言胜在语法简单,没太多的语法糖,你可以去看一些开源代码,基本没啥难度,其实 error 没问题,只是习惯了别的语言,需要适应下
me1onsoda
2024-08-15 09:07:34 +08:00
用 go 来刷题,有个明显的不爽,二维矩阵没法一步到位声明初始化
label
2024-08-15 09:13:24 +08:00
为什么 java 在鄙视链最底端, 被所有其它语言开发者鄙视
nxcdJaNnmyF9O90X
2024-08-15 09:25:14 +08:00
语言的趋势 肯定是大道至简 go 这种绝对是未来趋势 反而 java 这种又臭又长的裹脚布 终会被历史抛弃
securityCoding
2024-08-15 09:30:32 +08:00
人云亦云,先多写几个项目再说吧,等组织架构变动时隔壁组交接扔过来 100 多 c++微服务你就知道老实人的好了
panxi
2024-08-15 09:50:25 +08:00
因为 go 的设计哲学就是显示性和简单性, 比如在 go 中没有类似 python 的 in 操作的语法糖, 你得遍历 orz
artiga033
2024-08-15 09:52:37 +08:00
go 的错误处理 我记得官方当年自己推 go2 草案的时候都想过要解决这个问题,一堆人还搁那洗 不过也只是草案罢了 后来也没实现,他哪怕学一下 Swift 的`try?`或者 Rust 的`?`来替换下那几乎每个函数调用后面都有再占三行甚至四行的 if err return 呢

泛型完全不好用,很多时候同样的情况放 C# Rust 都是能自动推导的,比如我初始化结构体调用另一个 New 函数作为初始化字段,我这个字段都是显式泛型类型了,那个泛型函数的类型居然还要我再写一遍?

元编程能力全靠代码生成,难用的一 b ,当然这点其他语言也没好到哪里去

多返回值并非好设计,一旦哪个函数返回多个值那你的链式调用或者嵌套调用就不得不断,当然要是认为这变相保证了代码可维护性也不是不行...

不知道有没有人用过 golang 的 MongoDB ,只要对比一下就能发现 golang 的 map 和 slice 语法到底有多啰嗦

不过要说和 java php 比,那我肯定选 golang ,但是要是吹 golang 语法简单就怎么怎么着的,那我的评价是 go 就是个多了强大的标准库和语言级协程支持的 C 语言罢了

不过云原生时代需要容器体积相对小,又完全自包含的应用,go 确实是不二之选,其他语言要么像 python nodejs 镜像体积太大太乱,要么像 java C#都还在摸索 aot 编译的路上,Rust 入门难度又是地狱级的,golang 占主流也没什么奇怪的
p1gd0g
2024-08-15 09:53:45 +08:00
就全栈 crud boy 来说,没重载,没 linq ,没 partial ,有循环引用问题。同样的业务一定是 c# 更快,重构更方便。
当然和 c# 去比本身也不公平
noyidoit
2024-08-15 09:56:19 +08:00
@neoblackcap 所以我现在会绕开所有使用 CGO 的东西,比如 mattn/go-sqlite3
zacard
2024-08-15 10:00:21 +08:00
挺喜欢 go 的,很多 agent 类的项目都用 go 写的
InkStone
2024-08-15 10:03:21 +08:00
错误处理这块,带完备 checked exception (意思是 Java 这种就别来碰瓷了)的异常机制,或者 Rust 这种 sum type 支持的 Result ,都比 Go 的错误处理要舒服很多。

Go 的错误处理机制其实就是 C 的特化版,稍微调和了一下 C 的错误处理与返回值的矛盾,但也仅此而已了。
gowk
2024-08-15 10:10:18 +08:00
Go 好是好,但是写业务的时候总感觉哪里不对,想问大家,用 Go 写业务的体验如何
有没有什么最佳实践之类的
Rache1
2024-08-15 10:27:41 +08:00
@emSaVya #58

当调用层级越深,这东西越恶心,在我个人看来,方法内部调用链是不是有错误,交给最上层来决定就好了,除非你关心它,没必要一层层传出去。错误这种东西,大部分时候抛出了就说明进行不下去,无可恢复了,如果其中的某一层认为它可以恢复到预期,它就可以捕获了,然后返回正确的结果出去就好了。


比如 A->B->C->D->E 这种调用链,E 出了错误,其实完全可以由他的最上层( A )来处理就好了,甚至都可以留给全局异常兜底,没必要在每一次都写一下 if...err 。

yu1miao
2024-08-15 10:45:21 +08:00
@Trim21
不应该啊,Go 不允许运行时泛型,编译器会把泛型翻译成普通的类型。

以「泛型函数」为例,处理分为 2 步:
1. 具化( instantiation ):根据泛型函数的具体实参,以泛型函数 func foo[P T](param P) 为基础,生成一个不带泛型的普通函数 func foo(param int64) 这里假设传入实参类型为 int64 。然后将该调用绑定到生成的函数
2. 调用( invocation ):调用生成的普通函数

按理说,几乎不会有性能差别。
duty
2024-08-15 10:47:10 +08:00
@neoblackcap #27 我忘了哪个大佬说的了,“CGO 不是 GO”
vczyh
2024-08-15 10:47:12 +08:00
Go 写业务不是很爽,但是有 IDE 的话也能凑合,Go 最适合中间件和 CLI 这种东西,推荐下自己写的: https://github.com/vczyh/redis-lib

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1064987

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX