为什么在这种情况下需要 referencing/borrowing?

Why is referencing/borrowing needed in this case?

我是 rust 的新手,刚玩过一些代码:

fn array_leaders(arr: &[i32]) -> Vec<i32> {
    let mut res = Vec::new();
    for (i, left) in arr.iter().enumerate() {
        let right = arr.iter().skip(i+1).sum();
        if left > right { res.push(*left) };
    }
    res
}

出现以下错误:

error[E0277]: the trait bound `&i32: Sum<&i32>` is not satisfied
    --> src/lib.rs:5:42
     |
5    |         let right = arr.iter().skip(i+1).sum();
     |                                          ^^^ the trait `Sum<&i32>` is not implemented for `&i32`

现在,我发现我可以在 if 语句中向正确的变量添加一个 &

        if left > &right { res.push(*left) };

这解决了问题。我想明白为什么

这是因为 left 的类型为 &i32(由 .iter() 生成),但 right 的类型为 i32(由 sum() 生成) .

我们可以比较 *leftright(两个 i32)。

Rust 还可以通过引用进行比较:left&right(两个 &i32)。

比较的两边必须存在相同级别的间接寻址。

下面的简短示例试图说明这一点。

此外,如评论中所述,Rust 会尝试推导非严格强加的类型(当存在某些替代方案时)。 这里,left 的类型是由 .iter() 强加的,但是 sum() 的 return 类型可以推导出来。 然后 Rust 尝试找到匹配 &i32sum() 的实现,因为这个结果将与 &i32 (left) 进行比较。在这里找不到,因此出现错误。

fn main() {
    let a = 5;
    for b in 3..=7 {
        let r_a = &a;
        let r_b = &b;
        let cmp1 = a < b;
        let cmp2 = r_a < r_b;
        let cmp3 = *r_a < *r_b;
        println!("{} < {} --> {} {} {}", a, b, cmp1, cmp2, cmp3);
    }
}
/*
5 < 3 --> false false false
5 < 4 --> false false false
5 < 5 --> false false false
5 < 6 --> true true true
5 < 7 --> true true true
*/