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

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

正题:
自从开始正式关注之后,知乎 App 就开始推送大量的 Go 问题的回答(我没有在知乎上关注,应该是根据大数据)
其中绝大部分都是喷 Go 的
而且这个量非常的大 每天都会收到多篇
范围涵盖了 Go 的方方面面
这个量远远超过了我同样关注的 JS/Node
一开始不当回事 但是每天这么多推送
不禁让人重视这个问题
18667 次点击
所在节点    Go 编程语言
125 条回复
gongquanlin
2024-08-15 11:07:40 +08:00
除了写 interface 继承做策略工厂的时候比较麻烦,其他的写业务时候还能容忍
但是编译速度快 + 运行成本小 + 部署无需纠结环境 让我容忍了 go 所有的缺点,哈哈~
losephsky
2024-08-15 11:11:00 +08:00
唔,再早之前不是一堆人各种夸 golang 吗?
LanLiang
2024-08-15 11:12:51 +08:00
挺好的,说明用的人更多了
HappyAndSmile
2024-08-15 11:33:56 +08:00
10 多年前就认识?不太相信
jadeborner
2024-08-15 11:34:28 +08:00
go 已经不错了,还搁这挑三拣四的
uiosun
2024-08-15 11:39:31 +08:00
@emSaVya #7

- try ... catch 直接包裹住问题,不判断
- 对值的合法性进行判断

当初一直这样写,很简洁。

初转 go 的时候,最难接受的就是 120 行代码,15 个 err != nil 判断……属实有点多了,那会儿最希望的是:你直接 panic 吧,别抛给我了 orz
wysnxzm
2024-08-15 11:43:46 +08:00
刚看到的
assassing
2024-08-15 15:20:36 +08:00
@Rache1 在 Python 中统一错误处理写习惯了,这是我学习 Go 中最不习惯的地方。本意是让开发根据不同错误,就地给出不同解决恢复方案,但这与保持简单相悖。能写出恢复方法就能写出预防方法,防止异常发生。其他情况,同样只能打个日志干瞪眼。
hez2010
2024-08-15 17:33:06 +08:00
Go 的错误处理繁琐是一回事,更重要的是设计从根本上就是错误的。

result, err := foo()

一个函数是否发生错误只可能有两种情况,要么发生错误没有结果,要么不发生错误有结果。而 go 的设计直接给你来了个有无结果和有无错误的迪卡尔积,搞出来 4 种情况。
再有,如果你不去手动判断 err 是否为 nil ,则这个可能发生的错误就会直接被无时掉,意味着 go 的错误模型是默认无视掉所有错误。
这种用于错误处理设计不管出现在哪个语言里都是逆天的存在,与其说是错误处理,不如说它就是返回了个 tuple ,而实际上并不存在任何的错误处理机制。
Jinnrry
2024-08-15 17:48:28 +08:00
go 哪里破败不堪了?
1 、交叉编译,在座各位有能打的吗
2 、部署体验
3 、没有乱七八糟的包,没有各种语法糖,这是非常大的优点。给你一个上万行的 java 、python 、c++代码的项目,经过几十人接手,每人用着奇奇怪怪的语法糖简写,你看看你能看懂几行
4 、真要破败不堪,battmd 全都大面积在拿 go 写业务,这么多大公司都有病吗
BinaryDH
2024-08-15 17:50:53 +08:00
@wweerrgtc 十几年前认识 Go 这个单词而已
jlkm2010
2024-08-15 17:52:04 +08:00
go 的语法太怪异
Tsunayoshi
2024-08-15 18:33:17 +08:00
金斧头还是铁斧头。。能赚钱就得了
james122333
2024-08-15 19:12:53 +08:00
@hez2010

这叫多返回值 能返回的不只两个 其优点是避免了过多的结构嵌套 因为不是所有东西都值得写一个新的结构去包裹
重要的东西写结构更好 只是通常第二返回值为错误

错误处理方式当然直接中断是方便的 但中断本身消耗的资源就多一些 而且你不会知道什么时候会抛错 有些错误是不需要中断的这时候抛错的缺点就跑出来了 需要外部包裹捕获错误的代码 而且 go 并没有缺少中断抛错的方式 所以反而更好

近期我发现一种写法可能更好 那就是写个函数里头判断是否为 nil 不为则 panic 配上 go 里头强大的 import 很好用
go 的 import 具有普通 import 、import as 、import 仅作为依赖、import 至当前命名空间
比 java 的不知道好多少倍 不用写包全名 不用因命名空间让代码不够整洁
如下
package Panic

func PanicIfErr(err error) {
if err != nil {
panic(err)
}
}
=================================
package main

import (
"strconv"
. "example.org/panic"
)

func main() {
a := "123"
i, err := strconv.Atoi(a)
PanicIfErr(err)
println(i)
}
Trim21
2024-08-15 19:27:37 +08:00
@yu1miao #78 go 的泛型在面对接口的时候不是这么处理的,可以跑一下这个 bench 试试。这里的 BenchmarkExtra 多了一次接口虚表查询。

https://go.dev/play/p/jMm3oAbaLX0
gongym
2024-08-15 20:26:59 +08:00
只有两种语言,一种很多人骂,一种没人骂。
有人骂代表有人用,骂的人越多证明用的人越多。
再说了,从自己的需求出发,适合用什么语言就用什么语言。这年头还有不是全栈工程师的程序员嘛
geminikingfall
2024-08-15 20:37:57 +08:00
能用就好,其实除了范型太难看,其他倒没啥太大问题。
lix7
2024-08-15 20:58:15 +08:00
其实还好,写习惯了都差不多
dreamrover
2024-08-15 21:00:57 +08:00
我是曾经的 go 吹,现在的 go 黑,go 的各种限制太死了,玩了一圈感觉还是 C++香,自己写小东西用 nodejs 更爽,javascript 语法基本照抄 C ,特别灵活,库也特别多。
yu1miao
2024-08-15 21:03:36 +08:00
@Trim21 #95
`var buf = &Buffer{}` 拿的是结构体,
`var buf IBuffer = &Buffer{}` 拿的是接口,多一次虚表查询看上去是「接口调用绑定」带来的,感觉跟泛型无关

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

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

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

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

© 2021 V2EX