golang, 开发效率低执行效率高的语言?

7 天前
 iintothewind

最近因为偶然的原因, 不得不用了一段时间的 go. 经过这一段时间的使用, 发现这门语言实在是有太多不爽的地方, 所以就在这里吐槽一下, 看看是不是因为我理解不对, 还是这就是 go 语言以及生态的缺陷.

语法表达力非常差

go 的控制流非常简单: for, if, else, switch and defer 就是全部了 当然, 你如果之前对计算机语言所有的认知都来自于命令范式的语言(比如 C), 这并没有什么, 甚至觉得够用了.

但是对于偏函数式风格的语言, 这简直太简陋了, 函数式的控制流不仅有 for, if-else, 对于 switch 来说有更加强大的 pattern-match, 对于 defer 这种玩意, 有更好 try-catch-finally 替代, 而且你想怎么写就怎么写. 而且支持 unit, filter, map, flatMap 等等统一的操作.

golang 控制流的简陋直接造成了 golang 的语法表达能力差. 解决同样的问题, 需要更多更长的代码, 就像当年不支持 Lambda 特性的 Java 一样.

我就奇怪了: Java 没有支持 Lambda 以前, 人人骂 Java 代码啰嗦, 写起来累人, 到了 golang 了这么差的语法表达力, 怎么就成了简单清爽?

简陋敷衍的容错处理(Error Handling)

我接触到其它语言在写后端业务逻辑是, 对于 public 方法的入参是采取完全不信任的态度的. 原因很简单, 传进来的值在运行时存在非常多的可能, 最典型的就是 null 值一定要处理. 如果存在 a.b.c.d 等这样取值方式, 恐怕要不得不采用 Option 一层层去拿. 我可以理解有人说 Option 麻烦, 不管你用什么方式, 至少判空的逻辑是少不了的.

但是, Golang 是没有 Option 和 Try 的, golang 甚至连三元表达式都没有, 所以一般 Golang 是这样做的:

if a == nil { return nil, someError("...") }

b, err := a.b

if(err != nil) { return nil, someError("...") }

后面一大长串的 if(err != nil).......

如果你天天是写这样的代码, 你觉得这叫简洁?

少到寒酸的集合类型以及集合操作

其实 golang 的集合就只有个 array 和 map.

还有人说 array 的 slice 支持操作很方便啊? 我劝你醒醒, 看看其它语言吧, 就这几个操作哪个语言不支持啊?

Go 默认集合类型就是可变的, 所以所有对集合的操作, 实际上是修改集合自身. Go 是没有不可变集合这个概念的.

嗯, 找了找居然有人写了类似于 Linq 的 go-linq, 但是你看看相同的操作, go 得写多少代码吧, 而且每个操作结束时输出的变量居然时实现声明好再传进去的, 连直接输出到一个不可变集合的能力都没有.

蛋疼的数据库处理

其实我认为 Java 的数据库处理已经够老旧了. JDBC 标准已经很久没更新了, 而且很可能也不再更新了, 之前很多人期待的原生异步处理能力很可能不会再有了. Java 比较流行的 ORM 框架, hibernate 和 MyBatis 也已经非常老了, 老到都没办法在多线程环境下正常运行, 因为 Context 默认是单线程环境的. 但就这么老的 ORM 框架, 或许没办法跟.Net 的 linq 处理效率比一比, 但跟 Go 比起来也是好太多了.

来来来, Go 现在访问数据库, 有好的 ORM 框架吗? 有一个 sqlc 代码生成器, 大家已经觉得好太多了, 比自己写实在是快多了, 怎么不骂 Go 的数据库处理低效了, 就这??? 连个像样的 ORM 框架都没有.

鸡肋的泛型系统

Go 有泛型, 但又不支持方法级别的泛型.

Go 也没有泛型型变的概念.

所以你在接口上做一定程度的抽象, 绑定更多操作, 生成新的类型的实例是做不到的.

总结

Golang 其实真的只是一个 Better C 的定位, 当然这还是在开发效率上来说的, 就是仅仅** Better-Than-C **. 但 Golang 这简陋的语法, 相对于其它非常多的现代语言来讲, 还是差的很多的.

可能 Go 语言的那几个掌舵人就是典型的命令范式计算机语言的拥趸, "嗯, 我们可绝不会加入任何函数式的特性, 这会增加这个语言的复杂度, 降低编译速度, 让语言不纯粹...."

您说您的, 但是 Go 写写底层就好了, 毕竟比 C 好. C 可是连数据类型概念都没有, 从来只操作内存的.

现在结构体都允许写接收方法了, 也能写点泛型了, 内存都帮你回收了, 你还想怎样?

什么? 你说用 Go 写业务逻辑很痛苦???

谁让你用 Go 写业务逻辑了, 跟你说了别去跟那帮写 Java 的混一起, 他们就只会 spring, 除了 spring 啥都不会.

16126 次点击
所在节点    程序员
178 条回复
AceGo
7 天前
语法表达简单: 这对于大型项目来说是好事。大项目里,大部分时候在阅读别人的代码,review 、debug 等,代码看过去一眼能看懂在做什么,没有太多心智负担。想象下,全是 lambda 代码,是不是很头痛。ts 更灵活,同样的逻辑能有一百种写法,但阅读他人代码真的是一种折磨。
Error Handling:写 api 接口,一般会定义清楚用 400 还是 200 处理已知错误。通常是 200+errorMessage ,errorMessage 如果用 throw 抛出来就要区分哪些要在这层 catch ,哪些要在那层 catch ,就要定义各种 throw 区分,这也就跟 go 里的 error 一样的效果了。
yumenaka
7 天前
Go 的优点,是你可以在 10 年前发差不多的帖子,然后得到差不多的回答。

多少有的区别,是用 go 的人明显变多了。
PTLin
7 天前
你说的都对

错误处理不用返回-1 然后通过 error 判断具体错误,也不用搞一个 out 指针参数。函数能返回值和错误了,错误还能形成 list ,还能被 wrap ,大进步。

零值可用,cg 语言,指针逃逸分析确保了代码的内存安全,不会出现悬垂引用,垃圾数据,double-free 这种低级错误,大进步。

interface ,类型嵌入,结构体方法,极大加强了抽象能力,泛型能力,代码复用能力,相比 c 各种 cast 也是大进步。
工具链也比较完善,不用 autoconf ,make 那些玩意,文档系统也过得去,也是大进步。

但是这些也仅仅是让这个“better web google c”变得相比 50 多岁的 c 在人体工学上迈了一小步,相比人体工学做的更好的 native 语言还是差了不少,你可以说这些全是 features ,但是你非要说 go 多好,那我觉得就这个论坛,一个月一次的批判 go 就可以说明问题了。而且退一万步说,go 的发力场所就是 web ,非要用 c 说事多少有点有失公允了。
@minami
Martens
7 天前
月经贴
hez2010
7 天前
虽然但是,它执行效率也不高,编译速度特化使得编译优化做的依托答辩,编译出来的代码跑的还没预热后的 Java 快。
adoal
7 天前
@iintothewind

函数式语言(或者函数式特征的多范式语言)往往用的是 typed union 做 patterm match 来处理错误,比如 Haskell 里的 Maybe 和 Either 、Rust 里的 Option 和 Either ,从流程上来讲反而跟 go 的 if err 相像程度高过跟 try-catch 。

go 的错误处理,最大的坑是,本该用和类型处理的,硬是被它搞成了积类型。if err 的各种槽点,只是书写形式方面的审美问题。
victorc
7 天前
矫情,我现在天天撸 c++,不停地造轮子,踩坑,无比怀念 golang
xz410236056
7 天前
@javalaw2010 “我曾经也想找一门各方面都完美的语言,集各家编程语言之大成,从前端到后端,从 20 块的嵌入式硬件到几千亿美元的空间站,给广大开发者带来无与伦比的开发体验。结果就是陷在语言选择的囹圄里不能自拔,日月蹉跎”

你是否在寻找 c#?
dobelee
7 天前
看回帖 OP 适合花里胡哨的语法糖,这是 go 的弱项,换来的就是所有人都能轻易看懂代码。
aababc
7 天前
@xz410236056 #88 除了出身不好,那都好
layxy
7 天前
相比于目前常用的语言,比如 java,js(ts),python,go 确实不适合写业务,不是不能写,就是写起来有时候很啰嗦,远没有前面几个语言简单,但是优势也很明显,直接编译成目标平台可执行文件并且文件很小,无需依赖和预装环境,比较适合运维或者开发辅助工具或者中间件
guanzhangzhang
7 天前
if err 那个等你排错就知道了,java 好多报错很多人都不知道具体是啥原因,而 go 每个地方都 warp 上信息上一眼看出关键信息。
aloxaf
7 天前
关于 Go 有个有趣的点,那就是它官网的文档和 Playground 都不提供语法高亮,因为 Rob Pike 不喜欢语法高亮。

Go 的设计风格,从这里就可见一斑。
mxT52CRuqR6o5
7 天前
go 说是 better C ,但很多用 go 的地方压根儿不会考虑用 C 去写
securityCoding
7 天前
等你多维护几个跨语言项目就知道老实人的好了,一天天的语法塘跟个鬼画符似的
wupher
7 天前
- 传统的数据库 / web 使用 golang 主要是为了省钱,资源占用会比 spring 少很多

- 代价就是你说的,不省人。不过现在反正有 AI 了……

- golang 确实拿来写网络 App 更方便

- Rust 也不错,至少对于异常处理使用 Enum 真的比判断返回值和 try / catch 强。但它也有自己的问题

- 它们只是工具,重要的是使用工具的人
pigzzz
7 天前
go 就是编程界的遥遥领先,你讲他的不是,会有一堆拥簇者把你打成筛子
GreysonYee
7 天前
@kele999 之前看了个操作,可以用工具方法的形式来实现。

func IF[R any](condition bool, trueVal, falseVal R) R {
if condition {
return trueVal
}
return falseVal
}
reeco
7 天前
我现在更喜欢用 zig 来代替 golang ,同样优秀的跨平台编译以及标准库,就是手动 gc 麻烦了点
hunterzhang86
7 天前
开发效率低肯定谈不上,go 真的就是简单够用,拒绝一切花里胡哨。

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

https://www.v2ex.com/t/1101972

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

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

© 2021 V2EX