你使用哪种编码风格来处理三元运算符?

73

如果很短,我会将代码保持在单行。最近我一直在使用这种样式来处理更长或嵌套的三元操作符表达式。以下是一个人为制造的例子:

$value = ( $a == $b ) 
            ? 'true value # 1'
            : ( $a == $c )
                ? 'true value # 2'
                : 'false value';

你个人喜欢使用哪种风格,或者最容易阅读的风格?

编辑:(关于何时使用三元运算符)

通常我避免使用超过两层嵌套的三元运算符。当我在 PHP 模板脚本中输出变量时,我倾向于使用两层深度的三元运算符而不是两层深度的 if-else。


暂时标记为PHP,但我不确定这是否是该语言。 - ddaa
是的。我没有将它标记为PHP,因为该主题适用于所有具有类C语法的语言。 - Imran
添加了与语言无关的说明(因为它是这样),但保留了 PHP(因为这个示例是用 PHP 编写的)。 - ysth
这并不是一个适合于StackOverflow的好格式(请参见FAQ,因为它不是可以有“正确”答案的东西。您可能在程序员SE上会更加幸运。 - me_and
请尝试在Code Review上提问。 - kenorb
我经常和短开标签 <b><?=$x?"foo":"bar";?></b>一起使用。不知道在哪里可以阅读更多关于这种语法的内容 (: - bobble bubble
15个回答

104

三元运算符通常应该避免使用,但这种形式可以相当易读:

  result = (foo == bar)  ? result1 :
           (foo == baz)  ? result2 :
           (foo == qux)  ? result3 :
           (foo == quux) ? result4 : 
                           fail_result;

这种方式可以将条件和结果放在同一行上,便于快速浏览并理解正在发生的情况。


64
如果我必须这样使用它,我会使用一个switch语句。 - pilsetnieks
18
在这种特定情况下,你可以使用 switch 语句,因为它们是 == 比较,但它们也可以是任何表达式。在一般情况下,switch语句并非总是可行的。 - Simon Howard
2
@rmeador:所以你想要像Lisp的COND一样的东西,是吗?(setq foo 3) (cond ((>= foo 4) 'result1) ((= foo 3) 'result2) ((= foo 2) 'result3) ((<= foo 1) 'result4)) 返回结果为result2。 - Eggs McLaren
7
这个结构在PHP中需要加上更多的括号才能正确运行! - too much php
22
“三元运算符一般应避免使用”-为什么?这似乎更像是一个观点而不是规则。在许多情况下,三元运算符是一个很有用的工具,因为它可以代替if-else语句。也许我们也应该避免使用PHP,因为人们不知道如何正确地使用它呢? - Ryall
显示剩余12条评论

84

我尽量避免使用三元运算符编写嵌套条件语句。这会影响可读性,而且与使用条件语句相比没有额外的价值。

只有当它可以放在一行内,并且其含义非常清晰时,我才会使用它:

$value = ($a < 0) ? 'minus' : 'plus';

9
完全同意。只有当操作符作为单语句使用且字符数小于80个(包括缩进)时才可以使用。在之前的雇主那里,前任首席开发人员喜欢在1K个echo语句中间使用三元运算符。太可怕了。我在那个代码库里完全禁止了它的使用。 - jcoby
1
我将我的if块与其三元语句替代方案进行了比较,当三元语句有一些格式(括号、空格等)时,它比我的if块多20个字节,并且实际上难以阅读。当我优化了三元语句(但没有优化if块)时,它只比if块小两个字节,而且比之前更难以阅读。 - ICoffeeConsumer
嵌套三元运算符很容易被人们嘲笑,但如果你正在编写一个Automapper配置,并且需要一个Linq-to-SQL支持的表达式,那么它们突然就不那么糟糕了。 - user2880616

27

我有时会使用一种样式,我提出它是因为它还没有被提到,就像这样:

$result = ($x == y)
        ? "foo"
        : "bar";

但通常只有当把它们全部放在一行上会显得太长时才这样做。我发现让 = ? : 对齐可以使其看起来更整洁。


我会使用相同的样式,但是我不会将它们排成一行(我只使用制表符进行缩进,不会混合使用制表符和空格,这是我的不良风格观点)。 - jurchiks

25

个人而言,我只在一行上可以使用三元运算符时才会使用它。如果需要跨越多行,则是时候使用老式的

if else if else

17

PHP嵌套三元运算符的行为与普通三元运算符不同。

该语法通过了以下所有测试。参考自http://deadlytechnology.com/web-development-tips/php-ternary-syntax/

$myvar = ($x == $y)
?(($x == $z)?'both':'foo')
:(($x == $z)?'bar':'none');

参见: http://au.php.net/ternary

示例#3“非显然的三元行为”解释了为什么以下内容在PHP中不起作用。

$x = 1;
$y = 2;
$z = 3;   
$myvar = ($x == $y) 
       ? "foo" 
       : ($x == $z) 
         ? "bar" 
         : "none";  
$myvar == 'none'; // Good

$x = 1;
$y = 2;
$z = 1;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Good

$x = 1;
$y = 1;
$z = 3;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Bad!

$x = 1;
$y = 1;
$z = 1;   
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";  
$myvar == 'bar'; // Bad!

2
注意!在PHP中,嵌套三元运算符是一个棘手的问题。建议尽量避免使用,但我们都喜欢冒险。 - Zak Henry

13

三元运算符是编写简单 if 语句的一种简洁有效的方式。它们不应嵌套或难以阅读。记住:你只需编写软件一次,但它会被阅读 100 次。它的可读性应该比编写时更容易。


可读性为王,我个人非常喜欢这句话。 - cmeza

6

我倾向于在括号中写出条件语句: (a == b) ? 1 : 0


为什么?因为运算符有优先级。针对C++, PHP等编程语言,都有对应的优先级规则。 - Apostle
使真/假语句中的条件更易于辨别。我在代码中加上括号来表示所有条件。 - jurchiks

3

三目运算符可以使代码更加简洁优雅,最重要的是可以帮助你将重点放在正确的地方,避免重复。考虑使用它们,但不要通过这种方式使代码变得难以阅读。在VB.NET中:

    'before refactoring 
    If x = 0 Then                    ' If-Then-Else puts emphasis on flow control
        label = "None"
    Else
        label = Foo.getLabel(x)      '  If-Then-Else forces repeat of assignment line
    End If

    'after refactoring    
    label = If(x = 0, "None", Foo.getLabel(x)) ' ternary If puts emphasis on assignment

请注意,“不易阅读”和“我不习惯看到这个”不是同一件事情。

3
我不同意普遍的看法。我的条件运算符风格有点像Imran。如果它可以干净地放在一行上,我就把它放在一行上。如果它不能干净地放在一行上,我会将其分开,但我只使用一个制表符(4个空格; 我已经设置VS将制表符转换为空格)。我不会立即跳到if-else,因为很多时候条件运算符在语境上更有意义。(但是,如果在语境上没有意义,我就不使用它。)
此外,我不嵌套条件运算符。在那一点上,我发现它太难读了,是时候去更冗长的if-else风格了。

2

“刻意制造的例子”是我缩进的方式,除了我会从左边界进行缩进,而不是根据上一行的 (或其他符号。

对于三元操作符的反对者来说 - 可读性是关键。如果您认为它不能使代码更具可读性,请不要使用它。但是我发现这至少在某些情况下相反。


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