Go 凭什么不支持三元运算符?
这是一个很多其他语言工程师转 Go 语言的时间节点,这就难免不论一番比较。其中一个经典的运算上的就是 “三元运算符”:
为什么 Go 语言不支持三元运算符,Go 不支持三元运算符就是设计的不好,是历史在开倒车吗?
今天就由煎鱼来和大家一起摸索为什么。
三元运算符是什么
三元运算符,在典型的数学意义上,或者从解析器的角度来看,是一个需要三个参数的运算符。而我们日常中,最常见的是二元运算符:
x + y x / y x * y复制代码
还有一元运算符:
-a ~b !c复制代码
以及今天的男主角 “三元运算符”。在 C/C++ 等多种语言中,我们可以根据条件声明和初始化变量的习惯来选择性使用三元条件运算符:
int index = val > 0 ? val : -val复制代码
Go 使用三元运算符
想在 Go 语言里也使用三元运算符时,发现居然没有...想要实现与上面相同的代码段的方式似乎只能:
var index int if val > 0 { index = val } else { index = -val }复制代码
看上去十分的冗余,不够简洁。
为什么 Go 没有三元运算符
为什么 Go 没有 ?:
操作符,没有的话,官方推荐的方式是怎么样的。
通过 Go FAQ 我们可以得知:
Go 官方就是推荐我们使用前面提到的方式来替代,并且明确了如下态度:
Go 中没有
?:
的原因是语言的设计者看到这个操作经常被用来创建难以理解的复杂表达式。在替代方案上,if-else 形式虽然较长,但无疑是更清晰的。一门语言只需要一个条件控制流结构。
整体来讲,Go 语言的设计者是为了考虑可读性拒绝了实现三元运算符,"less is more." 也是标榜台词了。
社区争议
Go 语言的一些点与众不同,基本是大家皆知的。无论是 if err != nil,又或是本次的三元运算符,要大家用 if-else 替代:
if expr { n = trueVal } else { n = falseVal }复制代码
反对和同意
反对
因此有社区小伙伴给出了反对,基本分为如下几类:
认为 if-else 也有以类似情况能被滥用,设计者的理由不够充分,认为是 “借口”。
认为三元运算符的 “丑陋” 问题,是开发者的编码问题,而不是语言问题。三元在各种语言中很常见,它们是正常的,Go 语言也应该要有。
认为用 if-else 替代三元运算符也很麻烦,让开发者多读了 3-4 行和额外的缩进级别。
同意
认可这个决策的也有不少,为此给出了大量的真实工程案例。
一般来讲,我们用三元运算符是希望这么用:
cond ? true_value : false_value复制代码
你可能见过这么用:
cond ? value_a + value_b : value_c * value_d复制代码
还见过这样:
(((cond_a ? val_one) : cond_b) ? val_two) : val_three cond_a ? (val_one : (cond_b ? (val_two : val_three)))复制代码
还能嵌套三元运算符:
int a = cond_a ? val_one : cond_b ? val_two : cond_c ? val_three : val_four;复制代码
也能出现可读性更差的:
void rgb_to_lightness_( const double re, const double gr, const double bl, double &li) { li=((re < gr) ? ((gr < bl) ? bl : gr) : ((re < bl) ? bl : re) + (gr < re) ? ((bl < gr) ? bl : gr) : ((bl < re) ? bl : re)) / 2.0; }复制代码
说白了就是真实的代码工程中,大家见到过大量三元运算符滥用的场景,纷纷给出了大量的难理解的例子,让大家困扰不堪。
作者:煎鱼eddycjy
链接:https://juejin.cn/post/7023600289831714846