【问题标题】:Lazy evaluation not working as it should懒惰的评估不能正常工作
【发布时间】:2013-08-07 13:06:07
【问题描述】:

我不得不频繁地评估一个布尔表达式,所以我在它的类中将它转换为一个私有方法。这是给我带来麻烦的代码:

//"x", "y" and "team" are already defined
return (map.isWalkable(x,y) && 
    (!map.isOccupied(x,y) || map.getOccupant(x, y).getTeam() == team) );

就这个问题的目的而言,方法应该是不言自明的。现在, isWalkable 和 isOccupied 都返回一个布尔值,而 getOc​​cupant 是唯一返回对象引用的方法。问题是我在执行这段代码时遇到了 NullPointerException,这不应该发生,因为 isOccupied 当且仅当 map.getOc​​cupant != null 时才返回 true (这实际上是该方法返回的内容)。因此,对于支持从左到右的惰性布尔求值的语言(我假设 java 是,或者至少这是我能够阅读的),getOc​​cupant 方法永远不应该在它返回 null 时执行,对吗?

这是否比我想象的更依赖编译器?如果我使用 if 语句会更安全,还是我在这里遗漏了一些明显的东西,也许操作会反过来解决。

【问题讨论】:

  • 我认为你在 getTeam() 之后多了一个右括号。
  • 自己调试这么容易,为什么要在这里问?将每个子结果分配给它自己的变量并打印/测试它们以获取null。如果你速度慢的话,这是一个 3 分钟的工作。
  • 我很确定这不是原始代码(因为它的右括号存在解析问题),那么我们怎么知道您确实没有犯其他错误?
  • 您的一个右圆括号似乎放错了位置。它甚至可以编译吗?
  • 废话。好像我对你的说法感到困惑。真正的问题在于不平衡的括号。

标签: java lazy-evaluation


【解决方案1】:

问题是你的括号。试试

return (map.isWalkable(x,y) && (!map.isOccupied(x,y) || map.getOccupant(x, y).getTeam() == team));

【讨论】:

  • 感谢您指出这一点,我编辑了问题以修复它,但这不是导致异常的原因。
  • 只有在这段代码的两种情况下才会抛出 NullPointerException:map 为 null,当您尝试对 null 对象执行方法时抛出异常,或者返回的map.getOccupant(x,y) 为空,并且由于您试图在null 对象上调用getTeam(),因此引发了异常。
  • 是的,这个问题已经回答了,但我不能这么快就将其标记为已回答,因为 SO 不允许我这样做。不过还是谢谢你。编辑:看来不是。有人抹去了我要接受的答案...
【解决方案2】:

简单地说,不,懒惰的评估并没有被打破。你的代码是。 map 为 null,或者 map.getOccupant(x,y) 返回 null。

如果您将它们放在自己的行中并使用调试器检查它们,您会注意到“哦,不,我太愚蠢了,并没有注意到这一点”。

编译器、JVM 或其他任何东西都与此无关。

【讨论】:

    猜你喜欢
    • 2015-09-06
    • 2019-01-07
    • 2016-12-14
    • 1970-01-01
    • 2021-12-25
    • 2018-04-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多