【问题标题】:Why does (boolean ^ int > 0) work?为什么 (boolean ^ int > 0) 有效?
【发布时间】:2017-06-10 19:31:12
【问题描述】:

当你尝试做这样的事情时:

if (true ^ 1) {
  //do something
}

编译器有理由说运算符^ 没有为参数类型boolean 和int 定义。 但是如果你这样使用它:

if (true ^ 1 > 0) {
  //do something
}

代码可以编译(至少对于 Java 8)并且可以完美运行。 基本上这些操作:

false ^ -1 > 0 
false ^ 1 > 0
true ^ -1 > 0
true ^ 1 > 0

表现得像一个有效的逻辑异或:

     | ^
-----+--
 F F | F
 F T | T
 T F | T
 T T | F

谁能解释一下幕后发生了什么?

【问题讨论】:

  • 我建议你了解operator precedence
  • @Someprogrammerdude 公平地说,按位运算符的优先级低于比较运算符的优先级这一事实是这种情况下语言运算符优先级的一个特别不直观的方面。
  • 这就是你需要了解它的原因,@random :-)

标签: java syntax


【解决方案1】:

很简单:>precedence^ 高,所以

if (true ^ 1 > 0) {

等价于

if (true ^ (1 > 0)) {

相当于

if (true ^ true)

...这只是逻辑异或。

我永远不会编写这样的代码,请注意。看到无法以不同方式更清楚地编写的示例,我会感到惊讶。

【讨论】:

  • 我不明白为什么像 Java 和 C# 这样的面向安全的语言甚至允许这样的代码,而不是为了清楚起见而需要括号。毕竟,没有规定运算符的优先级必须是全序。
  • @CodesInChaos:良好的优先性 + 关联性可以为任何表达式明确定义行为。我不确定这是否是您所说的“总订单”...
  • @CodesInChaos 我认为答案是“安全”导向而不是“清晰”导向。这些是相关但不同的。安全要求没有歧义,这绝对是明确的。不过,以清晰为导向的语言的想法很有趣。我从来没有使用过限制语法 purely 的东西,因为它可能很难理解。这有点奇怪,因为清晰被广泛认为是良好发展的基本方面。
  • @JonSkeet:我相信 CodesInChaos 的“全序”意味着 Java 不需要将 ^> 定义为具有更高的优先级。可以定义语言,以便在相同的表达式中使用两者,不带括号,将是一个解析错误。例如,Haskell 允许以这种方式定义运算符:它会说“优先级解析错误:不能在同一个中缀表达式中混合‘^’[中缀 5] 和‘>’[中缀 5]。”
  • @wchargin:啊,我明白了——没有语言设计规则。是的,我同意这一点。这并不意味着总订单一定是坏事。
【解决方案2】:

因为>操作的优先级高于^,所以它相当于true ^ (1>0)操作相同类型(布尔型^布尔型)。

【讨论】:

【解决方案3】:

1 是 int 类型。

1 > 0 是布尔类型。

^ 表示异或;而且您不能对布尔值和整数进行异或运算。

换句话说:第一个表达式“1”的计算结果是一个数字;第二个表达式“1> 0”计算为布尔逻辑。背后的原因是运营商predecence

【讨论】:

    【解决方案4】:

    由于操作的顺序(优先级)很重要,> 的优先级高于^

    这里,首先我们检查1 > 0,然后第一个运算与第一个结果进行异或(^

    相当于if(true ^ (1 > 0 ))

    但是,当然你不能用 int 异或布尔值

    【讨论】:

      猜你喜欢
      • 2018-08-16
      • 2010-11-05
      • 1970-01-01
      • 2013-04-23
      • 2021-11-18
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      相关资源
      最近更新 更多