I'm new to rust and just played around with some code:
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
}
which gives the following error:
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`
Now, I've figured out that i could just add an &
to the right variable in the if statement:
if left > &right { res.push(*left) };
which solves the problem. I would like to understand why though
It's because left
has type &i32
(generated via .iter()
) but right
as type i32
(generated by sum()
).
We could compare *left
against right
(two i32
).
Rust also enables the comparison through references: left
against &right
(two &i32
).
The same level of indirection must be present on both sides of the comparison.
The short example below tries to illustrate this.
Moreover, as stated in a comment, Rust tries to deduce the types that are not strictly imposed (when some alternatives exist).
Here, the type of left
is imposed by .iter()
but the return type of sum()
could be deduced.
Then Rust tries to find an implementation of sum()
that matches &i32
because this result will be compared against &i32
(left
). This cannot be found here, thus the error.
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
*/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With