23

I'm having difficulty with Iterator's flat_map function and am not quite sure how to understand and tackle this compiler error.

I'm flat_mapping a list of file paths into two strings by serializing two structs:

let body: Vec<String> = read_dir(query.to_string())
    .iter()
    .enumerate()
    .flat_map(|(i, path)| {
        let mut body: Vec<String> = Vec::with_capacity(2);

        let entry = Entry { i };
        body.push(serde_json::to_string(&entry).unwrap());

        let record = parse_into_record(path.to_string()).unwrap();
        body.push(serde_json::to_string(&record).unwrap());

        body.iter()
    })
    .collect();
error[E0277]: a value of type `std::vec::Vec<std::string::String>` cannot be built from an iterator over elements of type `&std::string::String`
   --> src/main.rs:275:10
    |
275 |         .collect();
    |          ^^^^^^^ value of type `std::vec::Vec<std::string::String>` cannot be built from `std::iter::Iterator<Item=&std::string::String>`
    |
    = help: the trait `std::iter::FromIterator<&std::string::String>` is not implemented for `std::vec::Vec<std::string::String>`
sshashank124
  • 31,495
  • 9
  • 67
  • 76
Miranda Abbasi
  • 521
  • 2
  • 5
  • 10

1 Answers1

39

iter gives you an iterator over references. You need a consuming iterator which owns its values. For this, use into_iter instead. Here's a simple example:

fn main() {
    let result = (0..10).flat_map(|_| {
       let vec: Vec<String> = vec!["a".into(), "b".into(), "c".into()];
       vec.into_iter()
    }).collect::<Vec<_>>();
}

For a detailed explanation of the differences between iter and into_iter, refer to the following answer What is the difference between iter and into_iter?

sshashank124
  • 31,495
  • 9
  • 67
  • 76