为什么 Python、Go 和 Rust 都不支持三元运算符?( 三 )


总体而言,Python 设计者非常看重可读性与可维护性,不采用三元运算符而创造条件表达式语法,这是一个经过了开放讨论、谨慎评估与权衡取舍的结果 。
Go、Rust 为什么不支持三元运算符?考察完 Python 的设计原因后,我们再来考察“反派阵营”中两门最热门的语言 。
首先是 Go 语言,官网的 FAQ 专门列出了一个问题:“Why does Go not have the ?: operator?” 。
Go 语言不支持“?:”运算符,而是推荐使用原生的“if-else”写法 。文档的解释很简短,只有一段话:

Go 语言没有 ?: 运算符,因为语言的设计者们经常看到它被用来创建难以理解的复杂表达式 。虽然 if-else 形式比较长,但是它无疑更清晰易懂 。一个语言只需要一个条件控制流结构 。
接着是 Rust 语言,它的官方文档中似乎没有任何关于不支持三元运算符的解释 。但在查阅资料后,我发现它也有一段特殊的故事,非常有意思:在 2011 年 6 月时,Rust 曾经引入过三元运算符(#565),然而半年后,设计者意识到这个特性是多余的,因此又把它移除了(#1698、#4632)!
为什么三元运算符在 Rust 是多余的呢?因为它的 if 语法并不像其它语言是“语句(statement)”,而是一个“表达式(expression)”,这意味着你可以直接将 if 表达式赋值给变量:
// 若条件为真,得到 5,否则 6let number = if condition { 5 } else { 6 };这种语法形式足够简单明了,不就是将大家都熟悉的“if-else”直接用于赋值么,太方便了,替换成三元运算符的话,确实有点画蛇添足之感 。
另外,Rust 使用花括号划分代码块,因此上例的花括号内可以包含多条表达式,也支持换行,例如这个例子:
let x = 42;let result = if x > 50 {println!("x is greater than 50");x * 2 // 这是一个表达式,将返回的值赋给 result} else {println!("x is less than or equal to 50");x / 2 // 也是一个表达式,将返回的值赋给 result};这种用法,Python 是不可能做到的 。最关键的区别在于,Rust 的 if 是表达式而不是语句 。
这两个概念的区别是:
  • 表达式(expression)通常指的是由变量、常量、运算符等组成的一个可求值的代码片段,它的求值结果可以用到其它表达式或语句中 。
  • 语句(statement)通常指的是完成某个任务的单个指令或一组指令,例如赋值语句、条件语句、循环语句等,它没有返回值(或者为空),不能用于赋值操作 。
除了 Rust 外,还有一些编程语言中的 if 是表达式而不是语句,例如 Kotlin、Scala、F#、Swift,它们在理论上也不需要使用三元运算符 。(题外话:Swift 是个例外,它也有三元运算符 。Kotlin 有“?:”运算符,注意两个符号是连在一起的,val result = a ?: b 表示:如果 a 不为 null,则赋值给 result ;否则将 b 赋给 result)
由于有这种语言设计层面的区别,因此在面对“是否要支持三元运算符”这个问题时,Rust 和 Python/Go 的思考角度有着天然不同的起点 。知道了这种区别后,我们对编程语言会有更明晰地认知 。
回到本文的问题:为什么有些编程语言不采用主流的三元运算符语法呢?
不可否认,“?:”确实是一种简洁好用的设计,然而,标点符号的负面影响是过于抽象,可读性并不及“if-else”那样强 。另外,不同语言的设计风格与使用习惯,也会导致不同的选择 。
Python 在经过一番波折后,最后设计出了与众不同的条件表达式 。Go 语言明确表示不支持三元运算符 。Rust 先设计后舍去,主要的原因在于 if 表达式的语言基础 。
考察完这三个热门语言后,我相信你已收获了一个满意的答案 。如果是这样,请点赞支持一下本文吧!
最后,本文出自“Python为什么”系列,全部文章已归档在 Github 上,欢迎 star 和提 issue 。
??https://github.com/chinesehuazhou/python-whydo??
作者 l 豌豆花下猫  
【为什么 Python、Go 和 Rust 都不支持三元运算符?】来源 l Python猫(ID:python_cat)




推荐阅读