依赖于Java的短路求值(编码风格)

9

在布尔运算中,大量依赖短路是否是良好的编码风格?

我知道有些人喜欢这样做。例如,如果业务逻辑是“如果Alice不饿或者如果Alice和Bob都饿了”,而不是写

// if Alice is not hungry or both alice and bob are hungry
if (!A || A && B)` 

他会写作。
// if Alice is not hungry OR both alice and bob are hungry
if (!A || B)

这里的争议在于 || 是短路的,只有当第一个操作数为 false(也就是 A = true)时,才会对右操作数进行求值。

(令人讨厌的是,乍一看,你可能会认为这是一个 bug,但如果你把它改成更明显的形式,你会感到很愚蠢!)


1
在布尔逻辑中,这可能是可以的。大多数程序员通常能够理解。不过最好加上注释。 - Anubian Noob
1
这是一个观点问题,但根据我的经验,我经常看到Java短路用于简化布尔表达式。一旦你习惯了它,阅读起来并不太难。 - Kon
@AnubianNoob,问题就在于开发人员会留下评论,使谓词看起来更像一个错误! (即评论会说明业务逻辑,而谓词似乎正在执行其他操作!) - One Two Three
3
编译器(或在Java中的Hotspot)非常擅长于消除常见的子表达式。代码应该易读,符合要求且明显可见。 - kdgregory
1
你在第一个表达式中依赖于Java运算顺序 !A || A && B。我会像这样写:(!A) || (A && B)以使其对人更可读。 - Gilbert Le Blanc
显示剩余3条评论
5个回答

10

当然你可以并且应该在表达式中依赖于短路计算,但是你给出的例子只是不好的编程实践。表达式的逻辑应该与注释和测试的可读性一致。优化器完全理解布尔逻辑,并将优化掉任何看似低效的代码,这点你的队友可能会抱怨。

最重要的是让程序员能够清楚地理解代码。写巧妙的代码来证明自己有多聪明从来都不是一个好习惯。


8

这种风格是否好呢?是的,我认为大多数人都能欣赏这种习惯用语的风格:

myFoo != null && myFoo.myMethod();

3
这实际上与短路无关; 即使没有进行短路,这两个表达式也是等效的:
A    B       !A | A & B     !A | B
-----------------------------------
0    0       1               1
0    1       1               1
1    0       0               0
1    1       1               1
选择你认为将来更容易理解和管理的内容;任何明确传达你目的的内容都可以。在这方面,你的第一段代码片段似乎是最佳选择。

0

我认为在这种情况下,无论是否短路,结果都是一样的。他并不依赖于短路,而是简化所需逻辑。

在我看来,没有非常明确的黑白答案。个人而言,我不会像这样简化逻辑语句,因为当我稍后回到它时,很难阅读。添加额外的逻辑以明确解释我的检查不会


0

在这种情况下,您实际上并没有“依赖”短路评估。您只是简化了一个布尔表达式。使用&&&的逻辑相同。

短路的效果是:

  • 避免执行短路代码(可能具有副作用、抛出异常或无法终止)
  • 潜在地节省一些多余的计算

因此,短路不会以任何方式改变布尔结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接