要三元还是不三元?

时间:2008-10-01 23:27:46

标签: ternary-operator multilingual conditional-operator

我个人是三元运算符的拥护者:()? :;我确实知道它有它的位置,但是我遇到了许多完全反对使用它的程序员,还有一些经常使用它的程序员。

你对此有何感受?你看到了什么有趣的代码?

54 个答案:

答案 0 :(得分:230)

仅用于简单表达

int a = (b > 10) ? c : d;

不要链接或嵌套三元运算符,因为它难以阅读和混淆:

int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;

此外,在使用三元运算符时,请考虑以提高可读性的方式格式化代码:

int a = (b > 10) ? some_value                 
                 : another_value;

答案 1 :(得分:127)

由于无法在每个子表达式上放置断点,因此调试稍微困难一些。我很少用它。

答案 2 :(得分:79)

我爱他们,特别是在类型安全的语言中。

我不明白这是怎么回事:

int count = (condition) ? 1 : 0;

比这更难:

int count;

if (condition)
{
  count = 1;
} 
else
{
  count = 0;
}

编辑 -

我认为三元运算符使得所有东西都变得不那么复杂,而且比其他东西更整洁。

答案 3 :(得分:41)

链接我很好 - 嵌套,而不是那么多。

我倾向于在C中更多地使用它们,只是b / c它们是一个有价值的if语句,所以它减少了不必要的重复或变量:

x = (y < 100) ? "dog" :
    (y < 150) ? "cat" :
    (y < 300) ? "bar" : "baz";

而不是

     if (y < 100) { x = "dog"; } 
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; } 
else              { x = "baz"; }

在这样的作业中,我发现重构并且更清晰。

另一方面,当我在ruby工作时,我更有可能使用if...else...end,因为它也是一个表达式。

x =   if (y < 100) then "dog"
    elif (y < 150) then "cat"
    elif (y < 300) then "bar"
    else                "baz"
    end

(虽然,诚然,对于这个简单的事情,我可能只是使用三元运算符。)

答案 4 :(得分:39)

三元?:运算符仅仅是程序if构造的功能等价物。因此,只要您不使用嵌套的?:表达式,任何操作的函数表示的参数都适用于此处。但是嵌套三元操作会导致代码完全混乱(为读者练习:尝试编写一个解析器来处理嵌套的三元条件,你会欣赏它们的复杂性。)

但是在很多情况下保守使用?:运算符会导致代码实际上更容易读取。例如:

int compareTo(Object object) {
    if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
       return 1;
    if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
       return -1;
    else
      return 0;              
}

现在将其与此进行比较:

int compareTo(Object object) {
    if(isLessThan(object))
        return reverseOrder ? 1 : -1;         
    else(isGreaterThan(object))
        return reverseOrder ? -1 : 1;
    else        
       return 0;              
}

由于代码更紧凑,因此语法噪音更少,并且通过明智地使用三元运算符(仅与 reverseOrder 属性相关),最终结果并不特别简洁。

答案 5 :(得分:24)

这是一个风格问题,真的;我倾向于遵循的潜意识规则是:

  • 仅评估1个表达式 - 所以foo = (bar > baz) ? true : false,但不是foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
  • 如果我将它用于显示逻辑,例如<%= (foo) ? "Yes" : "No" %>
  • 只是真正用它来分配;永远不会流逻辑(所以永远不会(foo) ? FooIsTrue(foo) : FooIsALie(foo)三元流逻辑本身就是谎言,忽略最后一点。

我喜欢它,因为它对于简单的赋值操作来说简洁而优雅。

答案 6 :(得分:18)

像许多意见问题一样,答案是不可避免的:它取决于

类似于:

return x ? "Yes" : "No";

我认为 更简洁(我解析得更快)而不是:

if (x) {
    return "Yes";
} else {
    return "No";
}

现在如果您的条件表达式很复杂,那么三元运算不是一个好的选择。类似的东西:

x && y && z >= 10 && s.Length == 0 || !foo

不适合三元运营商。

顺便说一下,如果你是C程序员,GCC实际上有an extension允许你排除三元组的if-true部分,如下所示:

/* 'y' is a char * */
const char *x = y ? : "Not set";

假设x不是y,会将y设置为NULL。好东西。

答案 7 :(得分:12)

在我看来,只有在需要表达式的情况下才使用三元运算符才有意义。

在其他情况下,似乎三元运算符会降低清晰度。

答案 8 :(得分:11)

通过cyclomatic complexity的度量,if语句或三元运算符的使用是等效的。因此,通过该衡量标准,答案是,复杂性将与以前完全相同。

通过其他措施,例如可读性,可维护性和干燥(不要重复自己),任何一种选择都可能比其他选择更好。

答案 9 :(得分:10)

我经常在我被限制在构造函数中工作的地方使用它 - 例如,新的.NET 3.5 LINQ to XML构造 - 在可选参数为null时定义默认值。

受挫的例子:

var e = new XElement("Something",
    param == null ? new XElement("Value", "Default")
                  : new XElement("Value", param.ToString())
);

或(感谢asterite)

var e = new XElement("Something",
    new XElement("Value",
        param == null ? "Default"
                      : param.ToString()
    )
);

无论您是否使用三元运算符,确保您的代码可读是重要的。任何构造都可能变得不可读。

答案 10 :(得分:9)

我尽可能使用三元运算符,除非它使代码极难阅读,但那通常只是表明我的代码可能会使用一些重构。

总是让我感到困惑的是,有些人认为三元运算符是一个“隐藏”的特征,或者有些神秘。这是我开始用C语言编程时学到的第一件事,我认为它根本不会降低可读性。这是该语言的自然组成部分。

答案 11 :(得分:7)

我同意jmulder:它不应该用来代替if,但它有返回表达式或表达式内的位置:

echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;

前者只是一个例子,应该使用更好的i18n复数支持!

答案 12 :(得分:7)

(当天的黑客)

#define IF(x) x ?
#define ELSE :

然后你可以做if-then-else作为表达式:

int b = IF(condition1)    res1
        ELSE IF(condition2)  res2
        ELSE IF(conditions3) res3
        ELSE res4;

答案 13 :(得分:6)

如果您使用三元运算符进行简单的条件赋值,我认为没问题。我已经看到它(ab)用于控制程序流程甚至没有进行任务,我认为应该避免。在这些情况下使用if语句。

答案 14 :(得分:5)

我认为应该在需要时使用三元运算符。这显然是一个非常主观的选择,但我发现一个简单的表达式(特别是一个返回表达式)比完整的测试更清晰。 C / C ++中的示例:

return (a>0)?a:0;

与:相比:

if(a>0) return a;
else return 0;

您还可以在三元运算符和创建函数之间找到解决方案。例如在Python中:

l = [ i if i > 0 else 0 for i in lst ]

替代方案是:

def cap(value):
    if value > 0:
        return value
    return 0
l = [ cap(i) for i in lst ]

在Python(例如)中,需要经常看到这样的习语:

l = [ ((i>0 and [i]) or [0])[0] for i in lst ]

这一行使用Python中逻辑运算符的属性:它们是惰性的,如果它等于最终状态,则返回计算的最后一个值。

答案 15 :(得分:5)

我见过这样的野兽(它实际上更糟糕了,因为它是isValidDate并且每月和每天都进行检查,但我不会为了记住整件事而烦恼):

isLeapYear =
    ((yyyy % 400) == 0)
    ? 1
    : ((yyyy % 100) == 0)
        ? 0
        : ((yyyy % 4) == 0)
            ? 1
            : 0;
明显地,一系列if语句会更好(虽然这个比我曾经看过的宏版本更好)。

我不介意这样的小事:

reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;

甚至是一些棘手的事情:

printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");

答案 16 :(得分:5)

我喜欢他们。我不知道为什么,但是当我使用三元表达式时,我觉得非常酷。

答案 17 :(得分:4)

我几乎从不使用三元运算符,因为每当我使用它时,它总是让我想到的比以后当我尝试维护它时要多得多。

我喜欢避免冗长,但是当它使代码更容易上手时,我会为冗长而努力。

考虑:

String name = firstName;

if (middleName != null) {
    name += " " + middleName;
}

name += " " + lastName;

现在,这有点冗长,但我发现它比以下更具可读性:

String name = firstName + (middleName == null ? "" : " " + middleName)
    + " " + lastName;

或:

String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;

它似乎只是将过多的信息压缩到太小的空间中,而没有明确说明发生了什么。每当我看到使用三元运算符时,我总会找到一个似乎更容易阅读的替代方案......然后,这是一个非常主观的意见,所以如果你和你的同事发现三元非常易读,那就去吧。

答案 18 :(得分:4)

我喜欢在调试代码中使用运算符来打印错误值,所以我不必一直查找它们。通常我这样做的调试打印一旦我完成开发就不会保留。

int result = do_something();
if( result != 0 )
{
  debug_printf("Error while doing something, code %x (%s)\n", result,
                result == 7 ? "ERROR_YES" :
                result == 8 ? "ERROR_NO" :
                result == 9 ? "ERROR_FILE_NOT_FOUND" :
                "Unknown");
}

答案 19 :(得分:3)

正如其他人指出的那样,它们适用于短暂的简单条件。我特别喜欢它们的默认设置(有点像javascript和python中的 || 用法),例如。

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

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

SomeType& ref = pInput ? *pInput : somethingElse;

答案 20 :(得分:3)

嗯,它的语法很可怕。我发现函数ifs非常有用,并且通常使代码更具可读性。

我建议制作一个宏来让它更具可读性,但我确信有人会想出一个可怕的边缘情况(因为CPP总是如此)。

答案 21 :(得分:3)

我通常使用这样的东西:

before:

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

after:

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

答案 22 :(得分:3)

仅限于:

$ var =(简单&gt;测试?simple_result_1:simple_result_2);

KISS。

答案 23 :(得分:2)

我喜欢Groovy关于三元运算符的特殊情况,称为Elvis运算符:?:

expr ?: default

此代码计算为expr,如果它不为null,则为默认值。从技术上讲,它不是一个真正的三元运算符,但它肯定与它相关并节省了大量的时间/打字。

答案 24 :(得分:2)

我对待三元运算符很像GOTO。他们有自己的位置,但是他们通常应该避免使用这些代码来使代码更容易理解。

答案 25 :(得分:2)

对于简单的任务,例如根据条件分配不同的值,它们很棒。根据条件的不同,我会不会使用它们。

答案 26 :(得分:2)

如果你和你的同事都明白他们做了什么并且他们不是在大量的小组中创建的,我认为他们会使代码变得更简单,更容易阅读,因为代码更少。

我认为三元运算符使代码更难理解的唯一一次是当你在一行中有超过3或4个时。大多数人不记得他们是正确的优先权,当你有一堆它们时,它使得阅读代码成为一场噩梦。

答案 27 :(得分:2)

有很多答案说,取决于。我发现如果在快速扫描代码时看不到三元比较,那么就不应该使用它。

作为一个侧面问题,我可能还会注意到它的存在实际上有点像一个异常,因为在C中,比较测试是一种陈述。在Icon中,if构造(与大多数Icon一样)实际上是一个表达式。所以你可以做以下事情:

x[if y > 5 then 5 else y] := "Y" 

...我发现它比ternery比较运算符更具可读性。 : - )

最近讨论了将?:运算符添加到Icon的可能性,但有几个人正确地指出,由于if的工作方式,完全没有必要。

这意味着如果你可以用C语言(或任何其他具有ternery算子的语言)来做,那么你实际上根本不需要ternery算子。

答案 28 :(得分:2)

我最近看到了三元运算符的变体(好吧,有点)使得标准“()?:”变体似乎是一个清晰的典范:

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

或者,给出一个更切实的例子:

var Name = ['Jane', 'John'][Gender == 'm'];

请注意,这是Javascript,所以在其他语言中可能无法做到这一点(谢天谢地)。

答案 29 :(得分:2)

对于简单的情况,我喜欢使用它。实际上,读取/编写例如函数或类似事件的参数要容易得多。另外为了避免新线路我喜欢与我的所有if / else保持一致。

在我的书中,这将是一个很大的NO-NO。

所以,恢复,对于单个if / else我将使用三元运算符。对于其他情况,常规的if / else if / else(或switch)

答案 30 :(得分:1)

用它来:

  • 访问对象(数组)属性:
    var status = statuses[error == null ? 'working' : 'stopped'];
    
  • 返回声明:
    function getFullName(){
        return  this.isMale() ? "Mr. " : "Ms. "+ this.name;
    }
    
  • 初始化变量:

    var formMethod = DEBUG_FLAG == true ? "GET" : "POST";
    

    • 验证参数:

    function(object){
    var prop1 =  typeof object.property == 'undefined' 
             ? "default prop" 
             : object.property;
    //...
    }

代码示例在javascript中

答案 31 :(得分:1)

我会说逻辑表达式中条件的数量使得它更难阅读。这对于if语句是正确的,对于三元运算符也是如此。在一个完美的世界中,应该有一个总结理由来取得分支而不是其他分支。如果你的解释是“只有当这种状态的集群发生时”,那么它实际上更像是一个“商业规则”。

但是,在真实的世界中,我们不会添加中间步骤以将状态折叠成一个可表达状态,只是为了服从理想情况。我们已经对多个州做出推断,并且必须决定如何处理它们。

喜欢三元组,因为可以使用if语句执行任何

if( object.testSomeCondition()) { 
    System.exec( "format c:" );
}
else {
    a++;
}

另一方面:

a += ( object.testSomeCondition() ? 0 : 1 );

使清除目标是找到a的值。当然,与此相符,可能不应该不仅仅是合理的副作用。

  • 在我决定是否有时间重新处理上游条件之后,我使用if来查找长期或复杂的条件,以便我回答一个更简单的问题。但是当我使用if时,我仍然尝试执行并行处理,只是在不同的条件下。

    if (  user.hasRepeatedlyPressedOKWithoutAnswer() 
       && me.gettingTowardMyLunchtime( time )
       ) {
        ...
    }
    
  • 此外,我的目标是接近 - 单流处理。所以我经常尝试来做elseif只是走出共同路径的一步。当你进行大量的单流处理时,bug很难隐藏在你的代码中,等待那个跳出来破坏事物的条件。

  • 正如我上面所说,如果您使用三元组来设置一个的东西,或者您想要测试少量的情况以便将其设置为一个值,那么我只是喜欢三元组的可读性

  • 有一点需要注意 - &gt; NO COMPLEX true CLAUSES

    a = b == c ? ( c == d ? ( c == e ? f : g ) : h ) : i;
    

当然可以分解为:

a = b != c ? i
  : c != d ? h
  : c == e ? f
  :          g
  ;

它看起来像一个(压缩的)真值表。

请记住,更重要的因素是可读性的,其中一个是块长度,另一个是缩进级别。用三元组做简单的事情不会为进一步和进一步的缩进水平创造动力。

答案 32 :(得分:1)

三元运营商放下手。如果格式正确,它们并不复杂。以@paxdiablo的闰年为例:

$isLeapYear = 
   (($year % 400) == 0)
   ? 1
   : ((($year % 100) == 0)
      ? 0
      : ((($year % 4) == 0)  
         ? 1 
         : 0));

这可以写得更简洁,并且通过这种格式化可以更加可读:

//--------------test expression-----result
$isLeapYear = (($year % 400) == 0) ? 1 : 
              ((($year % 100) == 0)? 0 : 
              ((($year % 4) == 0)  ? 1 : 
                                     0));//default result

答案 33 :(得分:1)

我最近制定的经验法则是确定您是否应该使用三元运算符:

  • 如果您的代码在两个不同的值之间进行选择,请继续使用三元运算符。
  • 如果您的代码在两个不同的代码路径之间进行选择,请坚持使用if语句。

善待你的代码的读者。如果要嵌套三元运算符,请格式化代码以使嵌套显而易见。

答案 34 :(得分:1)

没有。他们很难读。如果/ Else更容易阅读。

这是我的意见。您的里程可能会有所不同。

答案 35 :(得分:0)

在小剂量下,它们可以减少行数并使代码更具可读性;特别是如果结果类似于根据计算结果将字符串设置为“是”或“否”。

示例:

char* c = NULL;
if(x) {
  c = "true";
}else {
  c = "false";
}

与之相比:

char* c = x ? "Yes" : "No";

在这样的简单测试中可能出现的唯一错误是分配不正确的值,但由于条件通常很简单,因此程序员不太可能弄错。让您的程序打印错误的输出并不是世界末日,应该在所有代码审查,工作台测试和生产测试阶段都应该抓住。

我现在反驳我自己的论点,现在使用代码覆盖率指标来帮助了解测试用例的好坏更加困难。在第一个例子中,您可以测试两个分配线上的覆盖范围;如果没有覆盖,那么您的测试不会执行所有可能的代码流程。

在第二个示例中,无论X的值如何,该行都将显示为正在执行,因此您无法确定是否已经测试了备用路径(YMMV取决于覆盖工具的能力)。

随着测试复杂性的增加,这更为重要。

答案 36 :(得分:0)

我非常喜欢它。当我使用它时,我将它写成if-then-else:每行一个用于条件,真实动作和错误动作。这样,我可以轻松地嵌套它们。

示例:

x = (a == b 
     ? (sqrt(a)-2)
     : (a*a+b*b)
     );

x = (a == b 
     ? (sqrt(a)-2)
     : (a*a+b*b)
     );
x = (a == b 
     ? (c > d
        ? (sqrt(a)-2)
        : (c + cos(d))
       )
     : (a*a+b*b)
     );

对我来说,这很容易理解。它还可以轻松添加子类或更改现有案例。

答案 37 :(得分:0)

使代码变小并不总是意味着它更容易解析。因语言而异。例如,在PHP中,鼓励空格和换行符,因为PHP的词法分析器首先以换行符开头,然后是空格。所以我没有看到性能问题,除非使用更少的空格。

为:

($var)?1:0;

好:

($var) ? 1 : 0;

这似乎不是一个大问题,但是在PHP中使用lexing代码,空格是必不可少的。另外,它也以这种方式读得更好。

答案 38 :(得分:0)

我使用并推荐三元组,以避免在逻辑微不足道的情况下使用代码行。

int i;
if( piVal ) {
    i = *piVal;
} else {
    i = *piDefVal;
}

在上述情况下,我会选择三元组,因为它的噪音较小:

int i = ( piVal ) ? *piVal : *piDefVal;

同样,条件返回值是很好的候选者:

return ( piVal ) ? *piVal : *piDefVal;

我认为紧凑性可以提高可读性,从而有助于提高代码质量。

可读性总是取决于代码的受众。

读者必须能够毫不费力地理解a ? b : c模式。 如果你不能推测这个,请选择长版本。

答案 39 :(得分:0)

如果您的三元运算符最终占据整个屏幕宽度,那么我就不会使用它。我只是检查一个简单的条件并返回单个值:

int x = something == somethingElse ? 0 : -1;

我们在制作中实际上有一些像这样的讨厌的代码...不好:

int x = something == (someValue == someOtherVal ? string.Empty : "Blah blah") ? (a == b ? 1 : 2 ): (c == d ? 3 : 4);

答案 40 :(得分:0)

三元运算符对于简明地生成逗号分隔列表非常有用。这是一个Java示例:

    int[] iArr = {1,2,3};
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < iArr.length; i++) {
        sb.append(i == 0 ? iArr[i] : "," + iArr[i]);
    }
    System.out.println(sb.toString());

产生:“1,2,3”

否则,最后一个逗号的特殊大小写会变得烦人。

答案 41 :(得分:0)

我同意这里许多海报的情绪。三元运算符完全有效,只要它被正确使用并且不会引入歧义(公平地说,你可以说任何运算符/结构)。

我经常在嵌入式代码中使用三元运算符来阐明我的代码在做什么。采用以下(为简化起见,过于简化)代码示例:

摘录1:

int direction = read_or_write(io_command);

// Send an I/O
io_command.size = (direction==WRITE) ? (32 * 1024) : (128 * 1024);
io_command.data = &buffer;
dispatch_request(io_command);

摘录2:

int direction = read_or_write(io_command);

// Send an I/O
if (direction == WRITE) {
    io_command.size = (32 * 1024);
    io_command.data = &buffer;
    dispatch_request(io_command);
} else {
    io_command.size = (128 * 1024);
    io_command.data = &buffer;
    dispatch_request(io_command);
}

在这里,我正在调度输入或输出请求。无论请求是读取还是写入,只有默认的I / O大小发生变化,过程才是相同的。在第一个示例中,我使用三元运算符清楚地表明过程是相同的,并且size字段根据I / O方向获得不同的值。在第二个例子中,两个案例的算法并不是很清楚(特别是代码增长的时间比三行长得多)。第二个例子更难以保持公共代码同步。在这里,三元运算符可以更好地表达代码的大部分并行性。

三元运算符具有另一个优势(尽管通常只是嵌入式软件的一个问题)。如果代码没有“嵌套”超过某个深度,则某些编译器只能执行某些优化(意味着在函数内部,每次输入if,loop或switch语句时,嵌套深度都会增加1,当减去1时,它会减少1)你离开了)。有时,使用三元运算符可以最小化需要在条件内部的代码量(有时到编译器可以优化条件的程度)并且可以减少代码的嵌套深度。在某些情况下,我能够使用三元运算符重新构造一些逻辑(如上例所示)并减少函数的嵌套深度,以便编译器可以对其执行额外的优化步骤。不可否认,这是一个相当狭窄的用例,但我认为无论如何都值得一提。

答案 42 :(得分:0)

在某些情况下我喜欢运算符,但我认为有些人倾向于过度使用它,并且它会使代码更难阅读。

我最近在一些我正在努力修改的开源代码中发现了这一行。

where 
               (active == null ? true : 
               ((bool)active ? p.active : !p.active)) &&... 

而不是

where ( active == null || p.active == active) &&...

我想知道在这种情况下三元使用是否会给LINQ语句增加额外的开销。

答案 43 :(得分:0)

使用三元运算符似乎没有人提及的一个原因,至少在支持类型推断的D语言中,允许类型推断适用于非常复杂的模板类型。

auto myVariable = fun();  
// typeof(myVariable) == Foo!(Bar, Baz, Waldo!(Stuff, OtherStuff)).

// Now I want to declare a variable and assign a value depending on some
// conditional to it.
auto myOtherVariable = (someCondition) ? fun() : gun();

// If I didn't use the ternary I'd have to do:
Foo!(Bar, Baz, Waldo!(Stuff, OtherStuff)) myLastVariable;  // Ugly.
if(someCondition) {
    myLastVariable = fun();
} else {
    myLastVariable = gun():
}

答案 44 :(得分:0)

如果您尝试减少代码中的行数或重构代码,那就去吧。

如果你关心下一个必须花费额外0.1毫秒才能理解表达式的程序员,那么无论如何都要去做。

答案 45 :(得分:0)

否(除非他们被滥用)。如果表达式是较大表达式的一部分,则使用三元运算符通常会更加清晰。

答案 46 :(得分:0)

string someSay = bCanReadThis? “不”:“是”;

答案 47 :(得分:0)

不,三元运营商不会增加复杂性。不幸的是,一些开发人员如此面向命令式编程风格,他们拒绝(或不会学习)其他任何东西。我不相信,例如:

int c = a < b ? a : b;

比同等的“更复杂”(但更详细):

int c;
if (a < b) {
    c = a;
} else {
    c = b;
}

或更尴尬(我见过):

int c = a;
if (!a < b) {
    c = b;
}

尽管如此,请根据具体情况仔细查看您的备选方案。假设一个受过普通教育的开发人员,请问哪个最简洁地表达了您的代码的意图并与之相关。

答案 48 :(得分:0)

有趣的轶事:我看到优化器称三元运算符为内联目的而不是相当于等效的“重”。我注意到这与Microsoft编译器有关,但它可能更广泛。

特别是这样的函数会内联:

int getSomething()
{
   return m_t ? m_t->v : 0;
}

但这不会:

int getSomething() 
{
    if( m_t )
        return m_t->v;
    return 0;
}

答案 49 :(得分:0)

我曾经在“三元运营商制作一条不可阅读的阵营”阵营,但在过去的几年里,我在适度使用时已经成长为喜欢它们。如果团队中的每个人都了解正在发生的事情,单行三元运算符可以提高可读性。这是一种简洁的做事方式,为了花括号而没有大量花括号的开销。

我不喜欢它们的两种情况:如果它们超出120列标记或者它们嵌入其他三元运算符中。如果您无法快速,轻松,可读地表达您在三元运算符中所做的事情。然后使用if / else等效。

答案 50 :(得分:0)

我认为这实际上取决于他们使用的背景。

这样的事情将是一种非常混乱,尽管有效的方式来使用它们:

 __CRT_INLINE int __cdecl getchar (void)
{
   return (--stdin->_cnt >= 0)
          ?  (int) (unsigned char) *stdin->_ptr++
          : _filbuf (stdin);
}

但是,这个:

c = a > b ? a : b;

非常合理。

我个人认为,当他们减少过于冗长的IF语句时,应该使用它们。问题是人们要么被吓呆了,要么就像他们一样,他们几乎完全被用来代替IF语句。

答案 51 :(得分:0)

取决于:)

在处理可能为空的引用时它们很有用(顺便说一句:Java真的需要一种方法来轻松比较两个可能为空的字符串)。

当你在一个表达式中嵌套许多三元运算符时,问题就开始了。

答案 52 :(得分:0)

如果没有三元运算符,有人会如何赢得混淆代码竞赛?!

我个人在适当的时候使用它,但我不认为我会嵌套它。它非常有用,但它有一些针对它的问题,因为它使代码更难阅读,并且在其他操作中使用其他语言(如Groovy的null-check)。

答案 53 :(得分:-1)

我很喜欢它......在适当的时候。

这样的东西太好了,就个人而言,我觉得它不太难以阅读/理解:

$y = ($x == "a" ? "apple"
   : ($x == "b" ? "banana"
   : ($x == "c" ? "carrot"
   : "default")));

我知道这可能会让很多人感到畏缩。

在PHP中使用它时要记住的一件事是它如何与返回引用的函数一起使用。

class Foo {
    var $bar;
    function Foo() {
        $this->bar = "original value";
    }
    function &tern() {
        return true ? $this->bar : false;
    }
    function &notTern() {
        if (true) return $this->bar;
        else      return false;
    }
}

$f = new Foo();
$b =& $f->notTern();
$b = "changed";
echo $f->bar;  // "changed"

$f2 = new Foo();
$b2 =& $f->tern();
$b2 = "changed";
echo $f2->bar;  // "original value"