3

I want to write concise code. Here is a snippet that fails for mysterious reasons:

let va: &mut Vec<f64> = &mut Vec::new();
va.push(5.0);

let avg: f64 = va.iter().sum() / 2.0;

The error message is:

error[E0283]: type annotations required: cannot resolve `_: std::iter::Sum<&f64>`
  --> src/main.rs:36:30
   |
36 |     let avg: f64 = va.iter().sum() / 2.0;
   |                              ^^^

Putting types everywhere doesn't help either.

let avg: f64 = va.iter().sum() as f64 / 2.0f64;

Error:

error[E0282]: type annotations needed
  --> src/main.rs:36:20
   |
36 |     let avg: f64 = va.iter().sum() as f64 / 2.0f64;
   |                    ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `S`
   |
   = note: type must be known at this point

The following code, which is a trivial rewrite, works:

let va: &mut Vec<f64> = &mut Vec::new();
va.push(5.0);

let sum: f64 = va.iter().sum();
let avg: f64 = sum / 2.0;

This problem is the same for any other arithmetic operation. What is the logic behind this behavior of the compiler?

My question is not about the Turbofish syntax.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ikamen
  • 3,175
  • 1
  • 25
  • 47
  • Related/Dup: https://stackoverflow.com/questions/52360464/what-is-the-syntax-instance-methodsomething – hellow Jul 03 '19 at 14:48
  • Perhaps experts can deduce how the other question helps me, but I definitely can't. – ikamen Jul 03 '19 at 14:54
  • As a side note, is there a reason why you write `let va : &mut Vec = &mut Vec::new()` instead the more usual `let mut va = Vec::new()`? – rodrigo Jul 03 '19 at 14:57
  • If you feel that you cannot understand the answer, it's a sign that you need to stick to other learning resources before trying Stack Overflow. The official [book](https://doc.rust-lang.org/stable/book) contains sections regarding how Rust infers parameter types. (e.g. [chapter 10](https://doc.rust-lang.org/stable/book/ch10-00-generics.html)) – E_net4 Jul 03 '19 at 14:59
  • @rodrigo there is no good reason for & in this example – ikamen Jul 03 '19 at 15:01
  • 3
    I think that the problem is that you think that `as f64` is a type annotation. But it is not a "type annotation", it is a "type cast", which is a very different thing. If you write `let a = expr;` and the compiler complains that the type of `expr` is not known, (type annotation required), then writing `let a: f64 = expr;` will work, because now `expr` must be `f64`. But if you write `let a = expr as f64;` you are forcing `a` to be `f64`, but `expr` still may be of any numeric type, so the compiler error persists. – rodrigo Jul 03 '19 at 15:04
  • The last comment is covered by the duplicate [What is the difference between type casting by setting the type of a variable and using `as`?](https://stackoverflow.com/q/56477618/155423) – Shepmaster Jul 03 '19 at 15:08
  • FWIW, the OP already knows *how* to solve this code, as it was [provided to them in a previous question](https://stackoverflow.com/questions/56871875/what-is-the-canonical-way-to-sum-the-elements-in-a-vec#comment100293007_56871875). – Shepmaster Jul 03 '19 at 15:12
  • I do not know how to solve it, even if some of the linked answers hint to solution. – ikamen Jul 03 '19 at 15:13
  • @rodrigo thanks, I have learned something – ikamen Jul 03 '19 at 15:13
  • 6
    @ikamen we have **literally** pasted the exact code you need, and then [linked to it](https://stackoverflow.com/questions/56871875/what-is-the-canonical-way-to-sum-the-elements-in-a-vec#comment100293007_56871875) in case you missed it. Here it is again, tailored to this instance: `let va = vec![5.0]; let avg = va.iter().sum::() / 2.0;` – Shepmaster Jul 03 '19 at 15:14
  • 2
    @ikamen If you don't like the content quality rules we enforce here on Stack Overflow, that's totally fine! Stack Overflow isn't for everyone. You may wish to look at other resources, such as [the Rust subreddit](https://www.reddit.com/r/rust/), [the Rust users forum](https://users.rust-lang.org/), or [the Rust Discord server](https://www.rust-lang.org/community). – Shepmaster Jul 03 '19 at 15:16
  • @Shepmaster I was impolite and I apologize. Yet it was a long path to this solution. Consider posting it as an answer so that newbies find it faster by googling. – ikamen Jul 03 '19 at 15:33

0 Answers0