嵌套的三元运算符vs嵌套if else,这在可读性方面更好

时间:2015-08-21 08:41:03

标签: language-agnostic ternary-operator conditional-operator

我在代码审查中找到了由我的团队成员编写的代码。它包含嵌套的三元运算符。我告诉他如果有多个嵌套用于可读性目的,请使用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;

随着新配置的出现,这段代码正在发生变化。

那么这里有什么好处?三元运算符还是其他?

5 个答案:

答案 0 :(得分:5)

我建议使用switch语句。它比三元和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");
}

答案 1 :(得分:5)

重新格式化代码非常清楚:

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,它容易出错。

答案 2 :(得分:2)

为此目的,在可读性方面,可能最好使用switch-case语句。

答案 3 :(得分:1)

转到开关。

我一直遵循的拇指规则(虽然不是很难)

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

2)两次条件检查,使用if(){} else if(){ } else{}构造

3)三个或更多人使用switch阶梯

“必须编写程序供人们阅读,并且只能偶然为机器执行。” - Harold Abelson,计算机程序的结构和解释

答案 4 :(得分:1)

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

(所有例子都在C#中)

public ColorEnum OpacityToColor(Opacity opacity)
{
  switch (opacity)
  {
    case Opacity.FIVE:
      return ColorEnum.BLACK;
    case Opacity.TEN:
      return ColorEnum.WHITE;
    case Opacity.FIFTY:
      return ColorEnum.RED;
    case Opacity.TWENTY:
      return ColorEnum.BLUE;
    case Opacity.FIFTEEN:
      return ColorEnum.PURPLE;
    default:
      throw new System.ArgumentOutOfRangeException("opacity");
  }
}

// Elsewhere
ColorEnum color = OpacityToColor(opacity);

如果您的语言具有整齐的字典/地图初始化语法(例如Python,C#),您还可以使用它来获得非常简洁明了的表示法:

public static readonly Dictionary<Opacity, ColorEnum> ColorByOpacity = 
  new Dictionary<Opacity, ColorEnum>
{
  {Opacity.FIVE, ColorEnum.BLACK},
  {Opacity.TEN, ColorEnum.WHITE},
  {Opacity.FIFTY, ColorEnum.RED},
  {Opacity.TWENTY, ColorEnum.BLUE},
  {Opacity.FIFTEEN, ColorEnum.PURPLE}
};

// Elsewhere
ColorEnum color = ColorByOpacity[opacity];