嵌套三元运算符 vs 嵌套 if else,后者在可读性方面更好
nested ternary operator vs nested if else, which is better in readability purpose
我在代码审查中找到了我的团队成员编写的代码。它包含嵌套的三元运算符。我告诉他如果出于可读性的目的存在不止一个嵌套,就使用 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
语句。它将比三元和 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
某处缺失,它很容易出现错误。
使用开关。
我有一个我一直遵循的经验法则(虽然不是硬性设定)
1) 只有一个条件求值,用三元运算符
2) 两个条件检查,用if(){} else if(){ } else{}
构造
3) 三个或更多 switch
阶梯
“程序要写出来给人看,顺便给机器看。”
― Harold Abelson,计算机程序的结构和解释
正如其他人所提到的,switch 是一个不错的选择。为了减少样板代码(中断、分配),我进一步建议将开关置于专用方法中:
(所有示例均使用 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);
如果您的语言有简洁的 dictionary/map 初始化语法(例如 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];
我在代码审查中找到了我的团队成员编写的代码。它包含嵌套的三元运算符。我告诉他如果出于可读性的目的存在不止一个嵌套,就使用 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
语句。它将比三元和 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
某处缺失,它很容易出现错误。
使用开关。
我有一个我一直遵循的经验法则(虽然不是硬性设定)
1) 只有一个条件求值,用三元运算符
2) 两个条件检查,用if(){} else if(){ } else{}
构造
3) 三个或更多 switch
阶梯
“程序要写出来给人看,顺便给机器看。” ― Harold Abelson,计算机程序的结构和解释
正如其他人所提到的,switch 是一个不错的选择。为了减少样板代码(中断、分配),我进一步建议将开关置于专用方法中:
(所有示例均使用 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);
如果您的语言有简洁的 dictionary/map 初始化语法(例如 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];