i == j == k 的意外结果?

Unexpected result from i == j == k?

在此代码中,我遍历 3D 域中的所有索引,并将“对角线”部分打印为

for (i, j, k) in {0..9, 0..9, 0..9}
{
    if i == j == k              // (1)
    //if (i == j) && (j == k)   // (2) -> gives expected result
    {
        writeln((i, j, k));
    }
}

我的预期结果是这样的

(0, 0, 0)
(1, 1, 1)
(2, 2, 2)
(3, 3, 3)
(4, 4, 4)
(5, 5, 5)
(6, 6, 6)
(7, 7, 7)
(8, 8, 8)
(9, 9, 9)

通过上面的第(2)行获得。但是如果我使用第 (1) 行,它会给出意想不到的结果,例如

(0, 0, 1)
(0, 1, 0)
(0, 2, 0)
...
(9, 7, 0)
(9, 8, 0)
(9, 9, 1)

所以我想知道我是否错误地使用了i == j == k? (仅供参考,上面的代码是由一些 Python 代码激发的,比如

for i in range(10):
    for j in range(10):
        for k in range(10):

            if i == j == k:
                print( i, j, k )

给出 (0, 0, 0), (1, 1, 1), ...)

好的,@Someprogrammerdude。

==是二元运算符,就是left-associative。文档在这里:

https://chapel-lang.org/docs/language/spec/expressions.html#precedence-and-associativity

当将布尔值 (i==j) 与整数 k 进行比较时(在 i==j==k 的上下文中),布尔值被隐式转换为整数并执行整数相等性检查。

FWIW,这些是我从其他语言得到的结果(但我对每种语言的用法可能是错误的,所以请这样......)。

C++

#include <iostream>
using namespace std;

int main() {
    int i = 2, j = 2, k = 2;
    cout << (i == j == k) << endl;
}
// => 0 (false), probably by interpreting it as (i == j) == k

礼拜堂

var i, j, k = 2;
writeln( i == j == k );
// => false (same as C++)

D

import std.stdio;
void main() {
    int i = 2, j = 2, k = 2;
    writeln( i == j == k );
}
// => Error: found == when expecting ) (and some related messages)

生锈

fn main() {
    let i = 2;
    let j = 2;
    let k = 2;
    println!( "{:?}", i == j == k );
}
// => Error
error: chained comparison operators require parentheses
 --> test.rs:6:25
  |
6 |     println!( "{:?}", i == j == k );
  |                         ^^^^^^^^^

error[E0308]: mismatched types
 --> test.rs:6:33
  |
6 |     println!( "{:?}", i == j == k );
  |                                 ^ expected bool, found integer
  |

Scala(这里的“>”是REPL)

> var i = 2
> var j = 2
> var k = 2
> i == j == k
         ^
  warning: comparing values of types Boolean and Int
           using `==` will always yield false
  res0: Boolean = false

科特林

> var i = 2
> var j = 2
> var k = 2
> i == j == k
error: operator '==' cannot be applied to 'Boolean' and 'Int'
i == j == k

尼姆

var i = 2
var j = 2
var k = 2
echo( i == j == k )

=> Error: type mismatch: got <bool, int>
but expected one of: 

proc `==`(x, y: bool): bool
  first type mismatch at position: 2
  required type for y: bool
  but expression 'k' is of type: int

expression: i == j == k

Python

> i = 2
> j = 2
> k = 2
> i == j == k
True

朱莉娅

> i = 2
> j = 2
> k = 2
> i == j == k
true

所以,除了 Python 和 Julia(它们是动态类型的,所以可能有点不同),似乎最近开发的静态类型语言往往会发出警告(甚至错误)反对使用 i == j == k。因此,如果 Python 用户可能会使用 Chapel,我想(对用户)给出一些警告(甚至错误?)消息可能会有所帮助。