缺少的布尔运算符如何仍然可以编译?

How does a missing boolean operator still compile?

我有这样的代码:

val pop: Bool = (
  (fsm === Fsm.None && canPop) ||
  (fsm === Fsm.Some && canPop && fooBar)
  (fsm === Fsm.Other && canPop && dragonFruit) ||
  (fsm === Fsm.Mom && canPop))

fsm 是一个基于 ChiselEnum 的状态机,其他信号只是布尔值。第二个语句行(fooBar 之后)缺少 ||。这会编译并运行,但会导致行为错误。我的问题是......为什么要编译?这似乎不是有效的语法。是吗?

请帮助我理解这一点。我只是花了很多天调试一个大电路才发现这个问题。

正确答案

问题是这是一个有点摘录。 Chisel 允许您执行 foo(bar)foo 中提取索引 bar 处的位。上面的代码,正如所写的那样,有点摘录,即使用户希望它是一个错误。

不幸的是,这是一个已知的陷阱,在没有误报的情况下犯错误是不合理的,同时仍然允许用户使用 () 语法进行位提取。

原答案不正确

这是符合 Scala 规则的有效语法。这里发生的事情是代码实际上是两条语句,但缩进令人困惑。相当于:

val foo = a + b  // Create an immutable value equal to "a + b".
  c + d          // A bare statement that adds "c + d", but doesn't use the result.

或臭名昭著的 C 错误,例如:

if (cond)
  foo();
  bar(); // bar() is always executed, but the indentation is confusing.

通常这是由于代码格式化程序或通过 linting 而引起的事情类型。但是,几乎所有语言都有这个问题。

为您的项目设置 Scalafmt 可能会有所帮助。