Note that the below example is not idiomatic and can be written more cleanly. However, it has been constructed to elicit responses. I am trying to understand what is happening behind the scenes that the compiler is unable to infer the type for a seemingly simple map()
(followed by collect()
) expression?
(The expression under-consideration is on the second from last line.)
#[derive(Debug)]
struct Rec {
a: String,
b: i32,
}
impl Rec {
fn from_row(row: &(String, i32)) -> Rec {
Rec {
a: row.0.clone(),
b: row.1,
}
}
}
pub fn main() {
let rows = [
(String::from("Apple"), 16),
(String::from("Tomato"), 18),
(String::from("Potato"), 24),
];
// cannot infer type (for res)
// consider giving `res` a type
let res = (0..rows.len()).map(|i| Rec::from_row(&rows[i]))
.collect();
println!("{:?}", res);
}
It works, when we add a type for the map expression.
let res: Vec<Rec> = (0..rows.len()).map(|i| Rec::from_row(&rows[i]))
.collect();
While the documentation for collect() does note the following about type-inference, this particular case seems to be pretty simple to cause problems with inference.
Because
collect()
is so general, it can cause problems with type inference. As such,collect()
is one of the few times you'll see the syntax affectionately known as the 'turbofish':::<>
. This helps the inference algorithm understand specifically which collection you're trying to collect into.