Language agnostic 嵌套的三元运算符与嵌套的if-else运算符相比,在可读性方面哪个更好

Language agnostic 嵌套的三元运算符与嵌套的if-else运算符相比,在可读性方面哪个更好,language-agnostic,ternary-operator,conditional-operator,Language Agnostic,Ternary Operator,Conditional Operator,我在团队成员编写的代码评审中找到了代码。它包含嵌套的三元运算符。我告诉他,如果为了可读性的目的有多个嵌套,就使用if-else。我们在那件事上有过争论 下面是代码 ColorEnum color = opacity == Opacity.FIVE? ColorEnum.BLACK : opacity == Opacity.TEN? ColorEnum.WHITE : opacity == Opacity.FIFTY? Co

我在团队成员编写的代码评审中找到了代码。它包含嵌套的三元运算符。我告诉他,如果为了可读性的目的有多个嵌套,就使用if-else。我们在那件事上有过争论

下面是代码

ColorEnum color = opacity == Opacity.FIVE? ColorEnum.BLACK : 
                opacity == Opacity.TEN? ColorEnum.WHITE :
                    opacity == Opacity.FIFTY? ColorEnum.RED :
                        opacity == Opacity.TWENTY? ColorEnum.BLUE :
                            opacity == Opacity.FIFTEEN? ColorEnum.PURPLE : null;
随着新配置的出现,此代码也在发生变化


那么这里有什么更好呢?三元运算符或if-else?

我建议使用
开关
语句。它的可读性比三值和
(如果有)更高

switch(opticity)
{
    case Opticity.FIVE: color = ColorEnum.BLACK;
    break;

    case Opticity.TEN: color = ColorEnum.WHITE;
    break;

    case Opticity.FIFTY: color = ColorEnum.RED;
    break;  

    ....

   default: printf("Error message\n");
}

为此,从可读性方面来说,switch-case语句可能是最好的。

只要重新格式化代码,就可以清楚地看到:

ColorEnum color = 
          opacity == Opacity.FIVE    ? ColorEnum.BLACK
       :  opacity == Opacity.TEN     ? ColorEnum.WHITE 
       :  opacity == Opacity.FIFTY   ? ColorEnum.RED 
       :  opacity == Opacity.TWENTY  ? ColorEnum.BLUE 
       :  opacity == Opacity.FIFTEEN ? ColorEnum.PURPLE 
       :  null;
LISP采用了
cond
构造,它具有相同的结构和语义,被认为是良好的实践。另一方面,Clojure还支持一种表单,该表单使用应用于不同值的单个谓词(每个子句一个)测试单个表达式的值,并将其称为
condp
——这将非常适合您的用例

带三元运算符的惯用用法作为表达式比
if-else
级联具有优势,因此只需一条语句即可将其分配给变量
if-else
将迫使您将作业拉入每个
then
子句中,引入更多样板文件和更多在正确性上失败的机会

switch
语句也可以作为备选语句,但它有以下缺陷:

  • 就像
    if else
    ,它不是一个表达式

  • 您仅限于单个表达式的不同常量值(表达式的类型也受到很大限制)

  • 由于缺少样板文件
    break
    的某些地方,它很容易出现bug

使用开关

我有一个我一贯遵循的经验法则(尽管不是硬性的)

1) 只有一个条件求值,使用三元运算符

2) 两个条件检查,使用
if(){}else if(){}else{}
construct

3) 三个或三个以上与
开关一起使用
梯形图

“程序必须是为人们阅读而编写的,而且只是为了让机器执行而编写的。”
―Harold Abelson,《计算机程序的结构和解释》

正如其他人所提到的,交换机将是一个很好的选择。为了减少样板代码(中断、分配),我进一步建议将开关置于专用方法中:

(所有示例均使用C#)

public ColorEnum OpacityToColor(不透明度)
{
开关(不透明度)
{
案例五:
返回ColorEnum.BLACK;
案例10:
返回ColorEnum.WHITE;
案例1.50:
返回ColorEnum.RED;
案例20:
返回ColorEnum.BLUE;
案例15:
返回ColorEnum.PURPLE;
违约:
抛出新的System.ArgumentOutOfRangeException(“不透明”);
}
}
//别处
ColorEnum color=不透明度TOCOLOR(不透明度);
如果您的语言有一个简洁的字典/映射初始化语法(例如Python、C#),您也可以使用它来表示非常简洁和清晰的符号:

公共静态只读字典ColorByOpacity=
新词典
{
{Opacity.FIVE,ColorEnum.BLACK},
{Opacity.TEN,ColorEnum.WHITE},
{Opacity.50,ColorEnum.RED},
{Opacity.two,ColorEnum.BLUE},
{Opacity.十五,ColorEnum.PURPLE}
};
//别处
ColorEnum color=ColorByOpacity[opacity];

我第一次在编写Java代码时听到对LISP的引用。;-)@Andreas最初的Java 1.0体系结构团队包含几个著名的Lisper:)因此,如果有表达式而不是常量(enum),我就不能使用switch@nilesh
switch
主要是关于性能的,并且被编译成表查找。这就是为什么只能使用预先确定类型的常量作为开关标签的原因。if-else也是一个语句,因此必须在每个then子句中重复赋值。样板通常会降低可读性,但这取决于您。仅向我们征求意见的问题不适合StackOverflow,因为这不是一个讨论论坛。请重新表述你的问题;关于“主观问题”的章节应该会给你一些想法。