三等号表达式求值

5
假设我们有3个变量,我们需要ASSERT它们可以全部等于-1,或者它们都不等于-1。我编写了以下代码:
x := 1;
y := 1;
z := 1;

ASSERT( (x = -1) = (y = -1) = (z = -1) );

我经常写这种针对两个变量的检查,但出乎意料的是三重比较也编译通过了,但它的结果与预期不符。对于(1, 1, 1)这样的值,我希望它能够评估为真。在变量值替换和简化之后,我们得到:

ASSERT( False = False = False );

我认为它应该被评估为True,但实际上并不是。那么这个三元比较是如何被评估的呢?


这怎么可能呢?有三个条件,难道都不符合吗? - David Heffernan
如果你有除了布尔值以外的任何其他类型,你将会得到一个“不兼容的类型”编译器错误;我猜这是一个特殊情况,因为布尔值很少使用“=”运算符进行比较。 - Cosmin Prund
2
没有什么奇怪的,False = False 等于 True,而 True <> False。 - Premature Optimization
(Weired!= 未解释)且(Weired ~= bizarre ~= unusual)。 - Cosmin Prund
2个回答

8
首先,= 运算符是一个二元运算符:它总是作用于一对值。因此,没有所谓的“三重相等”。编译器将评估一对值,并使用结果来评估另一对值。
当编译器看到多个链接的运算符时,需要使用所谓的“运算符优先级”将它们分组成一对对。如果想想我们在小学学习的基本算术运算符,就很清楚了。毫无疑问:3+2*4 的计算结果是什么:它等同于 3+(2*4)。如果有疑问,始终请自行添加分组。如果这样做,您会看到表达式等同于: ((False = False) = False),很明显它的计算结果为: (True = False)
你可能想要使用 AND 运算符并像这样分组你的初始 AssertASSERT(((x = -1) = (y = -1)) and ((y = -1) = (z = -1))) 然后我可能会将该表达式写成多行以使 AND 运算符更加明显(SQL 习惯),或者完全重写它。
Assert (
  ((x = -1) = (y = -1))
  and
  ((x = -1) = (z = -1))
);

或者这个变体:
Assert (
  ((x = -1) and (y = -1) and (z = -1))
  or
  ((x <> -1) and (y <> -1) and (z <> -1))
);

我的原则是:如果需要花费超过1秒钟的时间来确定运算符的优先级,请添加括号。


2
比较具有结合律: False=False=False 等同于 (False=False)=False。第一个 False=False 的结果为 True,导致比较 True=False,进而得到结果为 False。请注意保留 HTML 标签。

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