Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I collect the Lines iterator into a vector of Strings?

I'm trying to read the lines of a text file into a vector of Strings so I can continually loop over them and write each line to a channel for testing, but the compiler complains about collect:

use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::path::Path;

fn main() {
    let file = File::open(Path::new("file")).unwrap();
    let reader = BufReader::new(&file);
    let _: Vec<String> = reader.lines().collect().unwrap();
}

The compiler complains:

error[E0282]: type annotations needed
 --> src/main.rs:9:30
  |
9 |     let lines: Vec<String> = reader.lines().collect().unwrap();
  |                              ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `B`
  |
  = note: type must be known at this point

Without the .unwrap(), compiler says:

error[E0277]: a collection of type `std::vec::Vec<std::string::String>` cannot be built from an iterator over elements of type `std::result::Result<std::string::String, std::io::Error>`
 --> src/main.rs:9:45
  |
9 |     let lines: Vec<String> = reader.lines().collect();
  |                                             ^^^^^^^ a collection of type `std::vec::Vec<std::string::String>` cannot be built from `std::iter::Iterator<Item=std::result::Result<std::string::String, std::io::Error>>`
  |
  = help: the trait `std::iter::FromIterator<std::result::Result<std::string::String, std::io::Error>>` is not implemented for `std::vec::Vec<std::string::String>`

How do I tell Rust the correct type?

like image 875
Petrus Theron Avatar asked Dec 04 '18 10:12

Petrus Theron


Video Answer


1 Answers

Since you want to collect straight into a Vec<String> while the Lines iterator is over Result<String, std::io::Error>, you need to help the type inference a little bit:

let lines: Vec<String> = reader.lines().collect::<Result<_, _>>().unwrap();

or even just:

let lines: Vec<_> = reader.lines().collect::<Result<_, _>>().unwrap();

This way the compiler knows that there is an intermediate step with a Result<Vec<String>, io::Error>. I think this case could be improved in the future, but for now the type inference is not able to deduce this.

like image 53
ljedrz Avatar answered Nov 16 '22 01:11

ljedrz