写了几个月的业务了 写 err 真的吐了 牵扯到序列 /反序列话、有任何文件、io 操作的地方都会有 error
报的那么多 error 有啥用? 报那么多 error 没能解决问题 第一行成功 下面的几处 error 第一行的 error 岂不是白打了? 这种与业务无强关联的地方 与业务嵌套这么深 直接全局异常捕捉不就行了?
还有都 21 世纪了 居然不支持重载 输出一样 输入参数不一样 不能重载 就很无语。我写个方法功能一样 还得另外起个名字
这群设计者是学术界呆太久了?
写了几个月的业务了 写 err 真的吐了 牵扯到序列 /反序列话、有任何文件、io 操作的地方都会有 error
报的那么多 error 有啥用? 报那么多 error 没能解决问题 第一行成功 下面的几处 error 第一行的 error 岂不是白打了? 这种与业务无强关联的地方 与业务嵌套这么深 直接全局异常捕捉不就行了?
还有都 21 世纪了 居然不支持重载 输出一样 输入参数不一样 不能重载 就很无语。我写个方法功能一样 还得另外起个名字
这群设计者是学术界呆太久了?
101
hutoer Dec 26, 2021
@cmdOptionKana 那你看看 golang make 的用法:
make(map[string]string) make([]int, 2) make([]int, 2, 4) 按照你说的风格,要是变成多个函数了,会不会被吐槽? |
102
QingXuJiaZhi Dec 26, 2021
@hutoer 当然,我第一次听这种说法的时候,也是愕然了一下,但人家说的是有点道理。
说个题外话,另外一个 Go 语言相关的更震惊我说法是:语法高亮没有必要。 Rob Pike 平时使用一个自己做的编辑器“Acme”是不带语法高亮的,Go 团队里的另一个重要人物 Russ Cox 也使用 Acme 。事实上,可能有些人甚至没有察觉,Go 的文档服务 godoc (现在已迁移到 go.dev )里的示例代码全都没有语法高亮,但只要脑子里想的是如何解决问题,就会发现没有语法高亮一点影响都没有,甚至都忘记了自己看的代码是没有高亮的。 我自己的感受是,看代码时确实语法高亮的影响很小,但自己写代码时高亮还是有明显的辅助作用。 |
103
QingXuJiaZhi Dec 26, 2021
@hutoer make 选择这种类似重载的风格,主要因为这种自带函数有一半“占据关键词”的副作用,因此才不得不减少函数名。而在 strings, sort 之类的标准库里,就选择了显性的风格。
|
104
QingXuJiaZhi Dec 26, 2021
@hutoer 要不是怕占了关键词(保留词),换成多个函数名反而更好(从 Go 的审美角度看),我并不觉得会被骂(唯一被骂的理由只是占了保留词)。
|
105
hutoer Dec 26, 2021
@cmdOptionKana 我倒是觉得重载能降低心智负担、提升代码简洁渡,例如:
data := make([]int, 2) data := make([]int, 2, 4) 比下面的简洁 data := makeXX1([]int, 2) data := makeXX2([]int, 2, 4) 还有这种( Color 是构造函数) color = new Color(0,0,255) color = new Color("#FFFFFF") color = new Color(Color::RED) 比下面的简洁 color = new Color() color.setByRGB(0,0,255) color = new Color() color.setByHEX("#FFFFFF") color = new Color() color.setByName(Color::RED) |
106
LUO12826 Dec 26, 2021 想到以前讨论谷歌 material design 和 iOS 的设计风格时,某乎上有人大篇幅论述谷歌的右划侧边栏是如何比 iOS 的底部 tab bar 优秀的。然而后来,谷歌自己又加上了底部 tab bar
|
107
QingXuJiaZhi Dec 26, 2021
这个不需要重载啊,变长参数就可以了。
data := make([]int, 2) data := make([]int, 2, 4) 而这个 color = new Color(0,0,255) color = new Color("#FFFFFF") Go 的习惯是 c = color.New(0,0,255) c = color.ByHex("#FFFFFF") 从简洁的角度看差别不大。 (其中 color 是 package 名字,New 和 ByHex 是 public 函数) |
108
aloxaf Dec 26, 2021
@hutoer #99
这个例子举得不好,换我我肯定不会这么设计——「 Color::Color("#FFFFFF")」这种,显然是可能初始化失败的。如果并作一个 API ,在强迫你显式处理错误的语言中,就不得不为明明不可能出错的逻辑写上错误处理代码。 举个我觉得比较常见的「重载」更好的例子: string.replace('a', 'b') string.replace("abc", 'a') string.replace("abc", "def") string.replace("abc", a_function_pointer) ...(以下省略若干种排列组合)... |
110
maja Dec 26, 2021
噗
call/cc 用过没? 这玩意比宁那全局异常捕捉靠谱多了。 |
111
hutoer Dec 26, 2021
@cmdOptionKana golang make 会根据第一个参数做不同的处理,行为更像重载,变长参数不行。
另外,变长参数我反倒觉得是不良设计,尽量少用。 你说的 color.ByHex("#FFFFFF")这种方式,已经是牺牲可读性换取简洁性了。相对我的例子,还不是 OOP 的方式。 其实,我只是想说重载是有用的,而不是想证明没有重载不行。 |
112
Buges Dec 26, 2021 via Android
@hutoer go 的 make 只是缺乏泛型的 trick ,没啥好说的。
另外不要被 OOP 荼毒太深,constructor 本身就是糟粕,可读性简洁性都不如直接用函数。 Color::from_rgb(u8,u8,u8)和 Color::from_hex(String)返回类型都不一样,后者是可失败的(虽然在异常的语言中被隐藏了),难道该用同一个名字吗? 另外就算需要所谓的“重载”效果,用泛型是更好的选择。Color::from<T: Into<Color>>(t:T)->Color 甚至比你写多个重载的函数更“OOP”。 |
113
sxfscool Dec 26, 2021
非要和 java 一样么?为什么不去用 java
|
114
james122333 Dec 26, 2021
|
115
hutoer Dec 26, 2021
@Buges Color::from_rgb(u8,u8,u8)和 Color::from_hex(String)返回类型咋不一样了?都是 Color 实例呀。
泛型替代不了重载 至于“constructor 本身就是糟粕,可读性简洁性都不如直接用函数”,这个我就不讨论了,大家看问题的面不一样。 |
116
Buges Dec 26, 2021 via Android
@hutoer 因为后者可能会失败。粗略地说,前者返回 Color ,后者返回 Color | ParseError 。异常的语言可能会隐藏这一点,但用了 checked exception 同样可以体现出来。
泛型就是达到“重载”的效果最合适的方式,泛型代替不了重载的地方就不该用重载。 constructor 完全是多余的复杂度,这个概念根本就没有必要。new FancyClassName(params) 比 FancyClassName.new(params) 没有任何优势。反而让代码难读又难写。如: FancyClassName FancyClassName::FancyClassName(params){ blabla... } |
117
hutoer Dec 26, 2021
@Buges “后者返回 Color | ParseError”,这个说法不恰当,返回的还是 Color ,Parse 出错只不过抛异常。
前者函数内出错误( Color 这例子简单,大面上不会出错),也是会抛异常的。 “泛型代替不了重载的地方就不该用重载”,这个说绝对,下面这种: add(float a,float b) add(int a,int b,int c) add(char a,char b,char c) 业务毕竟多种多样的,有重载还是利于简化代码的。 方式 1 FancyClassName FancyClassName::FancyClassName(params){ blabla... } instance = new FancyClassName(params) 方式 2 FancyClassName FancyClassName::new(params){ blabla... } instance = new FancyClassName() instance.new(params) 我觉得还是方式 1 更好、更简洁。而且方式 1 规范了 constructor 方式 2 可以是 new 、create 、init 、build....,反而很乱 如果你说可以这样: instance = new FancyClassName.new(params) 那么 new 就是 constructor ,换了名字而已 |
118
hutoer Dec 26, 2021
instance = new FancyClassName.new(params) 这个写错了
instance = FancyClassName.new(params) 这个其实不算 constructor |
119
hutoer Dec 26, 2021
我看错了,把 FancyClassName.new(params) 当实例函数了
|
120
Buges Dec 26, 2021
@hutoer 异常只不过是一种不同的控制流,返回 Color throws ParseError 和返回 Result<Color,ParseError>本质上是一样的,都是返回数据,而这两者返回的数据“类型不同”。
你这个例子是完全可以用泛型的: fn add<A: IAddable<Output=A>>(a:A,b:A,c:A)->A{ } |
121
Buges Dec 26, 2021
@hutoer 上面没打完,constructor 没有提供额外的好处,限制了初始化函数的命名(这也是需要重载的一个主要原因),不能为不同的情况使用不同有意义的命名。至于命名有静态检查,并且一般都有特定的 convention,没什么混乱的。另外不要只从 OOP 的角度观察,简单的函数其实更好理解。
|
122
hutoer Dec 26, 2021
@Buges 抛出异常和返回错误值还是不一样的,调用的地方处理也不一样。就算是返回错误值,可以 Result<Color,Error>,Error 是基类,你这样 Result<Color,ParseError>,有其他类型的错误咋返回?所以 Color::from_rgb(u8,u8,u8)和 Color::from_hex(String)返回类型没有区别。
我那个例子,参数个数不一样的。 |
124
Buges Dec 26, 2021 via Android
@hutoer return 和 throw 是不同的控制流,需要用不同的方式处理,但本质上都是返回数据给调用方,无论通过 return 还是 throw 。实际“返回”的数据类型是不一样的。
如果签名写了 ParseError ,自然是表明该函数只可能返回这一种错误类型,如果还可以返回其他类型那自然要写成所有可能类型的 super type ,这个和 checked exception 本质是一样的。 参数个数不一样可以用 vararg ,或者包装到一个 collection literal 里,或者写成 macro 。如果只需要几种特定数量的参数,可以分别写成 add2 、add3 等不同函数,比起导致的问题重载并不能提供足够的好处。 |
125
agagega Dec 26, 2021 via iPhone
C++因为长期以来没有 optional 类型(而且即使有了也有额外 overhead ),所以构造函数只能用异常表示构造失败。
而不管是 C++风格的构造函数还是手写函数构造,都存在语义不明的问题。Swift 风格的具名参数和重载可以解决,并不一定需要带不同名字的函数。 但即使没有构造函数,这个创建对象的函数也还是需要某种方式来「创建」对象,这种 C 风格花括号的方式有是不如构造函数一样灵活。 另外在面向对象的继承关系里,构造函数就显得很自然,非构造函数虽然也可以做到类似效果,但就会很别扭。 |
126
fregie Dec 27, 2021
@partystart 什么叫好,什么叫不好,这几年开发者们已经用脚投票了,你觉得什么叫好,什么叫不好?
本身都不是面向对象的语言,你非拿它来写业务,写完了还说不好用,那能说你什么?但凡明白点面向对象的也会明白 go 本身就不适合写业务,编程语言没有银弹,不同语言有各自擅长的领域。 |
127
LoNeFong Dec 27, 2021
打起来 打起来 我就喜欢看 V 站语言战争, 一堆人瞎瘠薄操心!
赚几个钱啊? 房贷换完没啊? 真 tm 无聊 |
128
ly020044 Dec 27, 2021
我就喜欢看你们打字互喷,下次你们继续哈。
|
129
nmap Dec 28, 2021
别用不就得了嘛,人家也没逼着你用,也没让你掏一分钱
|
130
adoal Dec 29, 2021
你是不是对 PLT 的学术界有什么误解……
go 的错误处理硬生生把本该用 sum type 来做的事( either ok result or error info )做成了 product type ( a tuple with both ok result and error info )……哪个学术界是这么玩的? |