Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"type annotations needed" / "cannot infer type" when calling Iterator::collect

Tags:

rust

Why does this

fn main() {
    let test = "5% of foo".to_string();
    let result: i32 = test.split('%').collect()[0].parse().unwrap_or(0);
}

cause an error

error[E0282]: type annotations needed
 --> src/main.rs:4:23
  |
4 |     let result: i32 = test.split('%').collect()[0].parse().unwrap_or(0);
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `B`

This doesn't help either:

let result: i32 = test.to_string().split('%').collect()[0].parse().unwrap_or(0i32);
like image 686
Caballero Avatar asked May 28 '15 11:05

Caballero


People also ask

What happens after the first none is returned from an iterator?

It is also not specified what this iterator returns after the first None is returned. If you need fused iterator, use fuse. Creates an iterator that skips the first n elements. skip (n) skips elements until n elements are skipped or the end of the iterator is reached (whichever happens first). After that, all the remaining elements are yielded.

Why can't I use take_while () with iterators?

Because the closure passed to take_while () takes a reference, and many iterators iterate over references, this leads to a possibly confusing situation, where the type of the closure is a double reference: Stopping after an initial false:

What is an empty iterator in C++?

Takes each element, adds them together, and returns the result. An empty iterator returns the zero value of the type. When calling sum () and a primitive integer type is being returned, this method will panic if the computation overflows and debug assertions are enabled.

How do you skip the first n elements in an iterator?

If you need fused iterator, use fuse. Creates an iterator that skips the first n elements. skip (n) skips elements until n elements are skipped or the end of the iterator is reached (whichever happens first). After that, all the remaining elements are yielded.


1 Answers

fn main() {
    let test = "5% of foo".to_string();
    let result: i32 = test.split('%').collect::<Vec<_>>()[0].parse().unwrap_or(0);
}

collect() can become any type that implements FromIterator so a type hint is required.

Alternatively, you can make it more efficient by utilizing lazy iterators.

fn main() {
    let test = "5% of foo".to_string();
    let result: i32 = test.split('%').next().unwrap_or("0").parse().unwrap_or(0);
}
like image 165
Manishearth Avatar answered Oct 29 '22 16:10

Manishearth