我喜欢Groovy的三元运算符的特殊情况,称为Elvis运算符:?:
expr ?: default
如果expr不为空,则该代码计算为expr,否则计算为default。严格来讲,这并不是一个三目运算符,但它与之相关,并且可以节省很多时间和打字。
??
,空合并运算符:https://dev59.com/D3VC5IYBdhLWcg3wfhKL - Jarrod Dixon我认为逻辑表达式中的条件数量增加会使其更难阅读。这对于if语句和三元运算符都是正确的。在完美的世界中,应该有一个可总结的原因来选择某个分支而不是其他分支。如果您的解释是“只有当发生此状态集群时”,那么很可能真的更像是“业务规则”。
然而,在现实世界中,我们不会添加中间步骤来将状态折叠成一个可表达的状态,仅仅是为了遵守理想情况。我们已经推断出多个状态,并且必须决定如何处理它们。
我喜欢三元运算符,因为使用if语句可以做任何事情。
if( object.testSomeCondition()) {
System.exec( "format c:" );
}
else {
a++;
}
a += ( object.testSomeCondition() ? 0 : 1 );
这段代码明确表明目标是找到a
的值。当然,为了达成这个目标,可能不应该有过多的副作用。
在我决定是否有时间重构上游条件以回答更简单的问题之后,我会使用if
来处理长或复杂的条件。但是当我使用if时,我仍然尝试进行并行处理,只是在不同的条件下。
if ( user.hasRepeatedlyPressedOKWithoutAnswer()
&& me.gettingTowardMyLunchtime( time )
) {
...
}
此外,我的目标是接近单流程处理。因此,我经常尝试不使用else
,而if
只是通用路径上的一步。当您进行大量单流程处理时,很难让错误隐藏在代码中等待那个将跳出并破坏事物的条件。
正如我上面所说,如果您使用三元运算符设置一个值,或者您想要测试少量情况以设置它为一个值,则我只是喜欢三元运算符的可读性。
有一个例外->没有复杂的true子句
a = b == c ? ( c == d ? ( c == e ? f : g ) : h ) : i;
当然可以分解为:
a = b != c ? i
: c != d ? h
: c == e ? f
: g
;
看起来像是一个(压缩的)真值表。
记住,可读性有更重要的因素。其中之一是块长度,另一个是缩进级别。在三元运算中做简单的事情不会导致进一步的缩进级别。
$isLeapYear =
(($year % 400) == 0)
? 1
: ((($year % 100) == 0)
? 0
: ((($year % 4) == 0)
? 1
: 0));
使用这种格式化方式,可以更简洁地编写代码,并使其更易读:
//--------------Test expression-----Result
$isLeapYear = (($year % 400) == 0) ? 1 :
((($year % 100) == 0)? 0 :
((($year % 4) == 0) ? 1 :
0)); // Default result
我最近制定的一个经验法则是判断是否应该使用三元运算符:
同时,请对你的代码读者友好一点。如果你嵌套了多个三元运算符,请格式化代码以使嵌套关系明显可见。
我喜欢在某些情况下使用运算符,但我认为有些人倾向于过度使用它,这可能会使代码更难阅读。
最近我在修改一些开源代码时偶然发现了这行代码。
其中
(active == null ? true :
((bool)active ? p.active : !p.active)) &&...
不要使用
where ( active == null || p.active == active) &&...
我想知道在这种情况下,三元运算符的使用是否会给LINQ语句增加额外的开销。
int direction = read_or_write(io_command);
// Send an I/O
io_command.size = (direction==WRITE) ? (32 * 1024) : (128 * 1024);
io_command.data = &buffer;
dispatch_request(io_command);
代码片段 2:
int direction = read_or_write(io_command);
// Send an I/O
if (direction == WRITE) {
io_command.size = (32 * 1024);
io_command.data = &buffer;
dispatch_request(io_command);
} else {
io_command.size = (128 * 1024);
io_command.data = &buffer;
dispatch_request(io_command);
}
在这里,我正在分派输入或输出请求。无论请求是读取还是写入,过程都是相同的,只有默认的I/O大小会改变。在第一个示例中,我使用三元运算符来明确表明该过程相同,并且size
字段根据I/O方向获得不同的值。在第二个示例中,很难立即清楚两种情况的算法是相同的(特别是当代码比三行长得多时)。第二个示例将更难以保持公共代码同步。在这里,三元运算符更好地表达了代码的大致并行性质。
($var)?1:0;
好的:
($var) ? 1 : 0;
看起来不是一个大问题,但在 PHP 中词法分析代码时,空格是必须的。而且,这样读起来也更好。
如果你试图减少代码行数或重构代码,那就去做吧。
如果你关心下一个程序员需要花费额外的0.1毫秒来理解表达式,那么无论如何都要去做。
x = (a == b ? (sqrt(a) - 2) : (a*a + b*b) );对我来说,这很容易阅读。它还使得添加子情况或更改现有情况变得容易。
x = (a == b ? (sqrt(a) - 2) : (a*a + b*b) ); x = (a == b ? (c > d ? (sqrt(a) - 2) : (c + cos(d)) ) : (a*a + b*b) );
x = x if x else y
,但后来询问了别人的意见,得知它实际上可以简化为x = x or y
(http://stackoverflow.com/questions/18199381/self-referencing-ternary/18199562#18199562)。 - Scruffy