Reputation: 1994
I have a string from a CSV file that contains multiple lines:
header1,header2,header3
r1v1,r1v2,r1v3
r2v1,r2v2,r2v3
I am trying to push these into a Vec<Vec<String>>
:
// the csv is raw_string
let lines = raw_string.lines();
let mut mainVec = Vec::new();
for row in lines {
let mut childVec = Vec::new();
let trimmed = row.trim();
let values = trimmed.split(',').collect();
childVec.push(values);
mainVec.push(childVec.clone());
}
But I get the error
error[E0282]: unable to infer enough type information about `_`
--> src/main.rs:9:13
|
9 | let values = trimmed.split(',').collect();
| ^^^^^^ cannot infer type for `_`
|
= note: type annotations or generic parameter binding required
Upvotes: 1
Views: 6640
Reputation: 16765
Another solution, based on iterators:
fn main() {
let raw_string = r"rust
header1,header2,header3
r1v1,r1v2,r1v3
r2v1,r2v2,r2v3";
let main_vec = raw_string.lines()
.map(|s| s.trim().split(',').map(String::from).collect::<Vec<String>>())
.collect::<Vec<Vec<String>>>();
print!("{:?}", main_vec);
}
As @Simon Whitehead has already said, the the only thing you need to do with collect()
is to specify the type because this is a generic method. But it may also be deduced by the compiler itself in some circumstances.
The code above is pretty verbose about type specification: actually you may leave the Vec
's value type unspecified and let it be deduced by the compiler like this:
let main_vec = raw_string.lines()
.map(|s| s.trim().split(',').map(String::from).collect::<Vec<_>>())
.collect::<Vec<_>>();
For more information, see the definition of collect()
method.
Upvotes: 5
Reputation: 65087
You need to give the compiler a little hint as to what you want values
to be.
You can say you want it to be a vector of something:
let values: Vec<_> = trimmed.split(',').collect();
Working example in the playground
A few other notes about the code, if you're interested.
snake_case
. So the vectors should be called main_vec
and child_vec
.child_vec
does not need to be cloned when pushing it to the main_vec
. Pushing it to main_vec
transfers ownership and the loop redeclares the child_vec
and so the compiler can guarantee nothing has been violated here.Upvotes: 3