fn convert(filepath: String) -> Result<String, Box<dyn Error>> {
let f = File::open(filepath)?;
let mut reader = csv::Reader::from_reader(f);
let mut records: Result<Vec<_>, _> = reader.records().collect();
// records?.reverse();
for record in records {
println!("{:#?}", record);
}
Ok(String::from(""))
}
But I couldn't figure out how to use reverse() when record is a Result (uncommenting that line gives an error because apparently records?.reverse() moves records), so I thought, I can just change
let mut records: Result<Vec<_>, _> = reader.records().collect();
to
let mut records: Vec<_> = reader.records().collect()?;
which should be completely equivalent, right?
Nope...
error[E0282]: type annotations needed for `std::vec::Vec<_>`
--> src\main.rs:28:19
|
26 | let mut records: Vec<_> = reader.records().collect()?;
| ----------- consider giving `records` the explicit type `std::vec::Vec<_>`, with the type parameters specified
27 | // records?.reverse();
28 | for record in records {
| ^^^^^^^ cannot infer type
fn convert(filepath: String) -> Result<String, Box<dyn Error>> {
let f = File::open(filepath)?;
let mut reader = csv::Reader::from_reader(f);
let records: Result<Vec<_>, _> = reader.records().collect();
let mut records = records?;
records.reverse();
for record in records {
println!("{:#?}", record);
}
Ok(String::from(""))
}
I think the issue is the ? calls .into() on the error (so the error type is unknown), and the .collect has several types it can collect into. And the type inference can't resolve both at once, but I'm not certain.
You could also use turbo fish on the collect, if you tell it the error type.
fn convert(filepath: String) -> Result<String, Box<dyn Error>> {
let f = File::open(filepath)?;
let mut reader = csv::Reader::from_reader(f);
let mut records = reader.records().collect::<Result<Vec<_>, csv::Error>>()?;
for record in records {
println!("{:#?}", record);
}
Ok(String::from(""))
}
collect uses FromIterator which you can ask to make you any type,
? uses Try trait internally, which could theoretically work with any type,
and then ? uses From on the error type to convert from any type.
Type inference gets lost when you have conversion from something to anything, and anything to something. It doesn't want to choose that "anything" part.
If you want a 1-liner, you can use turbofish syntax: