当前位置:  开发笔记 > 编程语言 > 正文

要三元还是不三元?

如何解决《要三元还是不三元?》经验,为你挑选了17个好方法。

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

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



1> marcospereir..:

用于简单表达式:

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;


完全同意前几个陈述,但完全不同意你的"提高可读性"的例子.如果您要使用多行,为什么不使用if语句?
@ d03boy:因为if语句只是一个语句,当你想要的只是一个表达式时就不会这样做.
@ om-nom-nom的例子,这将使它成为if-expression而不是if语句,并且与?: - 运算符基本相同.
只是因为if else对于简单决策来说更加冗长:int a = 0; if(b> 10)a = some_value; 否则a = another_value; 你喜欢哪个?
@roe在某些语言中是表达式(例如在Scala中),因此`val x = if(true)0 else 1'是完全合法的

2> David Segond..:

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


这是反对我听过的三元运算符的最佳论据.我不买"不可读"的论点(听起来像是人们懒得习惯它),但这实际上有实质内容.

3> Ian P..:

我爱他们,尤其是在类型安全的语言中.

我不明白这是怎么回事:

int count = (condition) ? 1 : 0;

比这更难:

int count;

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

编辑 -

我认为三元运算符使得所有东西都比其他东西更简单,更整洁.


当变量是常量时,三元初始化在D或C++中更有用.例如`const int count = ...;`

4> rampion..:

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

我倾向于在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

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


+1我最近开始这么做了.我实际上甚至这样做来替换switch语句.

5> Ryan Delucch..:

三元?:运算符仅仅是程序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属性相关),最终结果并不特别简洁.



6> Keith Willia..:

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

只计算1个表达式 - 所以foo = (bar > baz) ? true : false,但不是foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false

如果我将它用于显示逻辑,例如 <%= (foo) ? "Yes" : "No" %>

只有真正用它来分配; 从不流动逻辑(所以永远不会(foo) ? FooIsTrue(foo) : FooIsALie(foo)) 三元中的流逻辑本身就是谎言,忽略了最后一点.

我喜欢它,因为它简洁而优雅,适用于简单的赋值操作.


你的两个第一个例子非常糟糕.比较结果已经是布尔值,因此您的三元运算符是无用的,只会使代码复杂化.

7> Sean Bright..:

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

对于这样的事情:

return x ? "Yes" : "No";

我认为这我更简洁(并且更快解析):

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

现在,如果您的条件表达式很复杂,那么三元运算不是一个好的选择.就像是:

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

对于三元运算符来说,它不是一个好的候选者.

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

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

哪个将设定xy假设y不是NULL.好东西.



8> John Mulder..:

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

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



9> Greg Hewgill..:

通过测量圈复杂度,使用if语句或三元运算符是等价的.因此,通过该措施,答案是否定的,复杂性将与以前完全相同.

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



10> Erik Forbes..:

我经常在我被限制在构造函数中工作的地方使用它 - 例如,新的.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()
    )
);

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


我喜欢你为了可读性而格式化它,所以很多都没有.

11> ilitirit..:

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

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


它可能导致可读性问题,尤其是在嵌套时.

12> 小智..:

(当天的黑客)

#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> PhiLho..:

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

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

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



14> Bill the Liz..:

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



15> PierreBdR..:

我认为应该在需要时使用三元运算符.这显然是一个非常主观的选择,但我发现一个简单的表达式(特别是一个返回表达式)比完整的测试更清晰.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中逻辑运算符的属性:它们是惰性的,如果它等于最终状态,则返回计算的最后一个值.


最后一行伤害了我的大脑......

16> JimDaniel..:

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



17> paxdiablo..:

我见过这样的野兽(实际上它更糟糕,因为它是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");

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有