是否应该使用三元运算符?

205

我个人是三元运算符的支持者:() ? :

我知道它有其适用场合,但我遇到过许多程序员完全反对使用它,还有一些程序员过于频繁地使用它。

你对此有何感觉?你见过哪些使用它的有趣代码?


9
当表达清晰明了时使用它,当它让人感到困惑时则避免使用。这是一个判断的问题。它可以使代码更易读,但仅适用于简单表达式。试图总是使用它与过度避免它一样有害。 - Abel
4
实际上,这是条件操作符。一个类似的问题在http://stackoverflow.com/questions/725973/what-do-fellow-net-developers-think-about-the-conditional-operator/726005上。 - Daniel Daranas
我有时会使用 x = x if x else y,但后来询问了别人的意见,得知它实际上可以简化为 x = x or y(http://stackoverflow.com/questions/18199381/self-referencing-ternary/18199562#18199562)。 - Scruffy
三元运算符可用于 if..else 结构无法使用的地方,例如在返回语句和函数参数中。虽然可以不使用三元运算符来实现相同的功能,但会导致代码变得更长,可执行文件变得更大。 - Arif Burhan
54个回答

3

我认为三元运算符就像GOTO语句一样。它们有其用处,但通常应该避免使用它们以使代码更易于理解。


3

正如其他人所指出的,它们非常适用于短小简单的条件语句。我特别喜欢将它们用于默认值(类似于JavaScript和Python中的||or),例如:

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

另一个常见的用途是在C++中初始化引用。由于引用必须在声明和初始化语句中同时声明和初始化,因此无法使用if语句。

SomeType& ref = pInput ? *pInput : somethingElse;

2
令人惊讶的是,这是关于初始化引用的第一次提到,这是少数几个地方之一,不能使用“if”代替?:。(我猜这不是一个特定于C++的问题...)出于同样的原因,在构造函数初始化列表中它们也是有用的。 - j_random_hacker

3

我通常在这样的事情中使用它:

before:

if(isheader)
    drawtext(x, y, WHITE, string);
else
    drawtext(x, y, BLUE, string);

after:

    drawtext(x, y, isheader == true ? WHITE : BLUE, string);

当然,在大多数编程语言中,您也不需要那个三元运算符中的“==true”部分。 - Michael Haren
我意识到,虽然我倾向于这样做只是为了使代码更易读,因为编译器应该会将其优化为与没有“==true”一样的东西。 - KPexEA
在任何语言中,你绝对不可能需要使用 "==true"。 - niXar
我曾经很难决定是否点赞。这个例子很好,但是在别人的代码中看到“==TRUE”这样的写法让我无法忍受。 - Peter Perháč

2

用它来:

  • 访问对象(数组)属性:

    var status = statuses[error == null ? 'working' : 'stopped'];
    
  • 返回语句:

    function getFullName(){
        return this.isMale() ? "先生 " : "女士 " + this.name;
    }
    
  • 初始化变量:

    var formMethod = DEBUG_FLAG == true ? "GET" : "POST";
    
  • 验证参数:

    function(object){
        var prop1 = typeof object.property == 'undefined'
                  ? "默认属性"
                  : object.property;
        //...
    }
    

代码示例使用JavaScript编写。


2

对于简单的if情况,我喜欢使用它。实际上,将其作为函数参数或类似内容进行编码/阅读要容易得多。此外,为了避免换行,我喜欢将所有的if/else保持在一起。

在我的书中,嵌套是绝对不可以的。

因此,总结一下,对于单个if/else,我会使用三元运算符。对于其他情况,则使用常规if/else if/else(或switch)。


2

对于简单的任务,比如根据条件赋予不同的值,它们非常好用。但是如果有更长的表达式依赖于条件,我不会使用它们。


2
如果您和您的同事了解自己在做什么,并且不是在大型团队中创建代码,那么我认为他们可以使代码更简单易读,因为代码量更少。
我认为三元运算符只有在一行中有三个或四个以上时才会使代码难以理解。大多数人不记得它们的优先级是基于右侧的,当您有一堆它们时,阅读代码会变成噩梦。

2
众所周知,“视情况而定”。如果在快速浏览代码时无法看到三元比较符号,则不应使用它。
作为一个副问题,我可能还要注意到,由于在C语言中,比较测试是一种语句,因此三元运算符的存在实际上有点反常。在Icon中,if构造(像大多数Icon一样)实际上是一个表达式。因此,您可以这样做:
x[if y > 5 then 5 else y] := "Y"

“我发现这比三元比较运算符更易读。:-)”
最近有一个关于向Icon语言添加 ?: 运算符的讨论,但是几个人正确地指出,由于 if 的工作方式,完全没有必要添加该运算符。
这意味着如果您可以在C(或任何其他具有三元运算符的语言)中执行此操作,则实际上根本不需要三元运算符。

2

我最近看到一种关于三元运算符的变体(或者说是类似的),使得标准的"() ? :"变体似乎成为了清晰易懂的典范:

var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]

或者,举个更具体的例子:
var Name = ['Jane', 'John'][Gender == 'm'];

请注意,这是JavaScript,所以其他语言可能不支持这样的事情(谢天谢地)。


1
哇,那太糟糕了!想象一下把几个这样的嵌套在一起!我唯一能看到的稍微有用的事情是如果你有一个返回2元素数组的函数:var Name = getNames()[Gender == 'm']; ...但那甚至更不可读! - nickf

2

仅当:

$var = (simple > test ? simple_result_1 : simple_result_2);

KISS原则在IT技术中很常见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接