Should I avoid Alternative Control Syntax?
作为一个自学成才的程序员,我从来没有真正让任何人解释过为什么某些东西应该或不应该被使用。一个例子(我几年前学过,经常使用)是替代控制结构语法:
1 | x = (y == true) ?"foo" :"bar"; |
我个人认为这种语法很容易理解,特别是对于简短的代码,但我不认为它在"原始"中有很多用处,所以我想知道在更传统的if上使用它是否是一种坏做法…其他结构?
事先谢谢。
作为一个自学成才的程序员,我只能给你我的意见,没有任何特别的权威支持。
我发现三元条件运算符(?:)对于没有副作用的表达式来说是完全可以接受的。一旦你开始用它来代表做某件事的决定,而不是做其他事,你(在我看来)就是在滥用它。
简而言之,控制结构用于构造代码流,运算符用于表达式。只要保持这样,代码就保持可读性。
条件运算符(有时称为三元运算符,但这在技术上不正确,请参阅Marc的注释)实际上不是"替代控制结构",有一些重要区别:
- 条件运算符是一个运算符,它提供一个值,用于表达式中。
- 如果/else是一个控制结构,它(当然)本身不会返回任何值。
- 条件运算符中的可选项也必须是表达式。
- if-else结构中的替代项可以是任意数量的语句。
当然也有相似之处:
- 每个函数都计算一个条件表达式。
- 只有适当的替代(表达式或块)才基于条件的布尔值进行计算。
- 两者都可以与同类语句链接在一起,形成更长的"类开关"语句。
一般来说,如果您正在评估副作用的可选表达式(即执行工作而不是返回值),那么对维护人员来说,使用条件运算符可能比使用if-else结构更容易混淆。
如果以下所有条件都为真,请使用条件:
- 你的条件陈述和替代陈述很容易理解。
- 这些表达式都没有任何副作用。
- 在将来,你不需要在替代品上有额外的行为(即副作用或额外的陈述)。
您给出的示例很好地使用了三元条件。
如果有疑问,请使用if else。当心把条件看成是另一种假设,并试图填塞那些不属于条件的东西。这类事情(尤其是在遗留代码中发现的情况下)会使人们完全不使用条件运算符。
这被称为三元表达式。如果可以用三元运算符清楚、简洁地表达意图,那么我就这样做。我通常画线并且有复合表达式(超过1个与&;&;或组合)
好:
1 | var x = (someVar > 42 ) ? ThisFunction() : ThisOtherFunction(); |
坏的:
1 | var x = (someVar > 42 && anotherVariable.IsSafeForConsumption() && IsNotProcessing ) ? ThisFunction() : ThisOTherFunction(); |
您所引用的语法通常称为三元条件运算符,它在语义上等于if/else子句,并且执行相同的操作。
过度使用SE结构的主要缺点是,它可以创建一些有点混乱的源代码,这些源代码的可读性可能不如使用if/else方法。对于那些不知道特定语法的人来说尤其如此。假设人们理解if/else,那么更可能->strike>100%安全。
此外,由于第三个运算符本质上是一个伪装成表达式的语句,因此可以这样做:
1 2 | x = (y == true) ?"foo" :"bar"; string instructions ="Please can somebody go and get me a" + x; |
并将其转换为:
1 2 | string instructions ="Please can somebody go and get me a" + ((y == true) ?"foo" :"bar"); |
请注意,附加括号是必需的。如果你看不到原因,试着自己编译它!
这是一个非常有用的特性,我一直在使用它。正如其他人提到的那样,要谨慎,不要编写有副作用的表达式,或者编写降低可读性的过于复杂的表达式。
在一个稍微不相关的注释中,为了上帝的缘故,请不要写这样的代码(我见过很多次):
1 2 3 4 5 6 | if (y == true) { weWantAFoo = true; } else { weWantAFoo = false; } |
相反,您应该这样做:
1 | bool weWantAFoo = (y==true); |
这只是使用条件语句的另一个示例,而不是在
除了在最基本的场景中使用它,我会说避免它。如果将两个构造编译为相同的精确msil,为什么要使用难以理解的构造?
对于我来说,这个问题是多程序员环境中的可读性和可维护性问题之一。
如果其他人必须阅读代码,或者稍后要返回代码,则需要使代码可读。
除非保持案例简单,否则使用三元运算符的代码很容易变得模糊和不可读。
- 保持简单
- 如果它变得更难读取,请重构为if else
条件运算符对于大多数devs应该非常熟悉。实际上,我只需要:
1 | x = y ?"foo" :"bar"; |
我觉得很容易理解。
1 | if(12345 == someVar) {...} // etc |
这个"const==variable"是为了避免出现"="与"=",但是由于c不将数字视为布尔值,因此这是一个非常罕见的问题,而且(在c)更常见的是看到更清晰的:
1 | if(someVar == 12345) {...} // etc |
因为如果您错过了这个额外的=它通常不会编译。