相对于标准的if-else语句,条件?:运算符有哪些好处和缺点。其中明显的分别是:
条件?:运算符
- 在处理直接值比较和赋值时更短,更简洁。
- 似乎不如if/else结构灵活。
标准If/Else
- 可适用于更多情况(例如函数调用)。
- 通常冗长而无必要。
对于每个语句,它们的可读性似乎各不相同。在初次接触到?:运算符后的一段时间内,我花了一些时间来理解它的工作方式。您是否建议在任何可能的情况下使用它,还是坚持使用if/else,因为我与许多非程序员一起工作?
相对于标准的if-else语句,条件?:运算符有哪些好处和缺点。其中明显的分别是:
条件?:运算符
标准If/Else
对于每个语句,它们的可读性似乎各不相同。在初次接触到?:运算符后的一段时间内,我花了一些时间来理解它的工作方式。您是否建议在任何可能的情况下使用它,还是坚持使用if/else,因为我与许多非程序员一起工作?
我基本上建议仅在结果语句非常短并且与if/else等效语相比具有显着简洁性而不损失可读性时使用它。
好的例子:
int result = Check() ? 1 : 0;
不好的例子:
int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;
return
作为三元运算符的结果之一。例如:“check() ? return 1 : return 0;” 是行不通的,但“return check() ? 1 : 0;”可以。在编程中发现这些小问题总是很有趣的。 - CSSreadonly int speed = (shiftKeyDown) ? 10 : 1;
不同于:
readonly int speed;
if (shifKeyDown)
speed = 10; // error - can't assign to a readonly
else
speed = 1; // error
类似地,您可以将三元表达式嵌入其他代码中。这不仅使源代码更加紧凑(有时也更容易阅读),而且还可以使生成的机器码更加紧凑和高效:
MoveCar((shiftKeyDown) ? 10 : 1);
使用lambda表达式可能会比调用同一个方法两次生成更少的代码:
if (shiftKeyDown)
MoveCar(10);
else
MoveCar(1);
当然,这也是一种更方便、更简洁的形式(打字更少,重复更少,如果您需要在if/else中复制代码块,可以减少错误的机会)。在像这样的“常见模式”情况下:
object thing = (reference == null) ? null : reference.Thing;
...使用三元操作符可以使代码更快速地阅读/解析/理解(一旦你习惯了它),相比冗长的if/else等价物,所以它可以帮助你更快地理解代码。
当然,仅仅因为它是有用的并不意味着在每种情况下都是最好的选择。我建议只在短代码中使用它,其中含义明确(或通过使用?:
更加清晰)- 如果您在更复杂的代码中使用它,或者将三元操作符嵌套在彼此之内,它会使代码难以阅读。
const
是一个常量,即在声明它的语句执行后不能被更改。 - Jason Williamsreadonly
吗?我一直认为const
意味着“在编译时解析并在使用的地方内联”。 - Nolonar如果我有很多重复的代码,通常会选择三元操作符。
if (a > 0)
answer = compute(a, b, c, d, e);
else
answer = compute(-a, b, c, d, e);
使用三元操作符,可以通过以下方式实现。
answer = compute(a > 0 ? a : -a, b, c, d, e);
b
、c
、d
和 e
进行处理,我会这样做:aVal = a > 0 ? a : -a; answer = compute(aVal,b,c,d,e);
。 - corsiKacompute(...)
的第一个参数是 a > 0 ? a : -1
,这个表达式与其他逗号分隔的参数是分开计算的。不过,很遗憾,C++缺乏处理逗号分隔值元组的符号表示法,因此即使 a > 0 ? (a, b, c, d, e) : (-a, b, c, d, e)
也是非法的,没有任何类似的东西可以在不更改 compute
自身的情况下工作。 - Tony Delroy当进行Web开发时,如果我想将一个变量设置为请求中发送的值(如果定义了该变量),或者将其设置为某些默认值(如果未定义),那么我发现这特别有用。
一个非常酷的用法是:
x = foo ? 1 :
bar ? 2 :
baz ? 3 :
4;
foo
为假,则整个表达式将直接计算为4,而不会执行其他判断。请注意避免该问题。 - Tom Busby// With
button.IsEnabled = someControl.HasError ? false : true;
// Without
button.IsEnabled = !someControl.HasError;
if(<boolCondition>) {
<variable> = <value>;
}
else {
<variable> = <anotherValue>;
}
可以轻松转换成:
<variable> = <boolCondition> ? <value> : <anotherValue>;
在需要使用if/else if/else、嵌套if/else或者导致多行代码评估的if/else分支逻辑的情况下,我建议避免使用三元操作符。在这些情况下使用三元操作符很可能会导致代码难以阅读、混乱且难以管理。希望这可以帮到你。
varA = boolB ? valC : valD;
我偶尔使用它,因为这样写出东西所需的时间更短...不幸的是,这种分支有时会被其他浏览你代码的开发人员忽略。此外,代码通常不会很短,所以我通常通过将 ? 和 : 放在单独的行上来提高可读性,像这样:
doSomeStuffToSomething(shouldSomethingBeDone()
? getTheThingThatNeedsStuffDone()
: getTheOtherThingThatNeedsStuffDone());
然而,使用if/else块的最大优点(也是我更喜欢它们的原因)是,在稍后添加一些附加逻辑到分支中会更容易。
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else {
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else if (shouldThisOtherThingBeDone()){
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
虽然上面的回答是有效的,我也同意可读性的重要性,但还有两个需要考虑的进一步点:
这使得使用三元运算符特别简洁:
string GetDrink(DayOfWeek day)
=> day == DayOfWeek.Friday
? "Beer" : "Tea";
如果你有类型 T1
和 T2
,它们都可以被隐式转换为类型 T
,那么下面的代码不会起作用:
T GetT() => true ? new T1() : new T2();
(由于编译器试图确定三元表达式的类型,并且T1
和T2
之间没有转换,因此无法工作。)
另一方面,下面的if / else
版本可以正常工作:
T GetT()
{
if (true) return new T1();
return new T2();
}
因为T1
被转换为T
,同时T2
也是如此。
SomeCheck() ? DoFirstThing() : DoSecondThing();
--你必须使用表达式来返回一个值。 - Dan Tao