繁体   English   中英

当运算符优先级表明不应该进行短路评估时,为什么这样做?

[英]Why does short-circuit evaluation work when operator precedence says it shouldn't?

JavaScriptJava中 ,equals运算符( ===== )的优先级高于OR运算符( || )。 然而,两种语言( JSJava )都支持if语句中的短路:

当我们有if(true || anything()) ,不评估anything()

您还可以使用以下表达式: true || foo == getValue()) true || foo == getValue()) - 例如在输出语句中,例如console.log(...); ,或在作业中。

现在,根据运算符优先级,不应该发生短路,如=== = == > || 在优先权方面。 (换句话说,首先应该进行比较,因为相等检查具有比OR比较更高的优先级,因此应该调用getValue() 。但它确实如此。 不调用getValue() (可以通过将输出语句放入其正文中来轻松检查)。

为什么(当运算符优先说它不应该时,短路工作)?
还是我困惑的事情?

还是我困惑的事情?

你是。 我认为将优先权视为分组而非排序要简单得多。 它会影响评价的顺序,但仅仅是因为它改变了分组。

我不确定Javascript,但在Java操作数总是按从左到右的顺序进行评估。 ==优先级高于|| 只是意味着

true || foo == getValue()

被评估为

true || (foo == getValue())

而不是

(true || foo) == getValue()

如果你只是考虑这种方式的优先级,然后考虑评估总是从左到右(例如, ||的左操作数总是在右操作数之前进行评估),那么一切都很简单 - 而getValue()是从未因短路而评估过。

要从等式中消除短路,请考虑以下示例:

A + B * C

...其中ABC可以只是变量,或者它们可以是其他表达式,例如方法调用。 在Java中,保证将其评估为:

  • 评估A (并记住以后)
  • 评估B
  • 评估C
  • 将评估BC的结果相乘
  • 使用乘法结果添加评估A的结果

请注意,即使*具有比+更高的优先级,仍然在BC之前评估A 如果你在排序方面考虑优先级,请注意在加法之前乘法仍然如何发生 - 但它仍然满足从左到右的评估顺序。

根据语言规范, https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24

在运行时,首先计算左侧操作数表达式; 如果结果具有布尔类型,则进行拆箱转换(第5.1.8节)。

如果结果值为true,则条件或表达式的值为true,并且不评估右侧操作数表达式。

所以如果你有a || b==c a || b==c ,它不被解释为(a || b) == c ,因为|| 正如您在教程中找到的那样,优先级较低。 相反,它被解释为a || (b==c) a || (b==c) 现在因为a||的左侧 ,首先评估它。

在这种情况下没有运算符优先级。 你在质疑的是在f(callback)语句中甚至在f之前评估的callback函数。 这不可能发生。

另一方面,在JS中|| 是少数几个可以在展会上观看懒惰的地方之一。 ==操作数(好像它是一个类似于全功能语言的中缀函数)需要两个参数,左边的一个首先得到评估。 如果它解析为true则第二个参数甚至不会被评估。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM