Ich habe eine Liste von CSV-Dateien und ich möchte einen Iterator über die Zeilen aller Dateien erzeugen. Ich verwende so flat_map()
:Geliehene lokale Variable in verschachtelten Lambda
extern crate csv;
extern crate rustc_serialize;
use std::path::Path;
use std::fs;
// simple struct used by the csv crate to deserialize the csv line into this Value
#[derive(RustcDecodable, RustcEncodable)]
pub struct Value {
pub id: String,
}
// I have an iterator over some csv files,
// I want an iterator of all the lines of all the files
fn do_stuff<I>(files: I)
where I: Iterator<Item = std::path::PathBuf>
{
let iter = files.flat_map(|f| {
let mut rdr = csv::Reader::from_file(f).unwrap().has_headers(false);
rdr.decode() // <- decode() takes rdr by ref
.map(|r| {
let b: Value = r.unwrap();
b.id //takes some values
})
});
// do stuff with iter
}
fn main() {
let paths: std::fs::ReadDir = fs::read_dir(".").unwrap();
do_stuff(paths.map(|p| p.unwrap().path()));
}
jedoch der borrow checker damit nicht glücklich ist:
error: `rdr` does not live long enough
rdr.decode().map(|r| {
^~~
note: reference must be valid for the block suffix following statement 0 at 22:7...
});
//do stuff with iter
}
note: ...but borrowed value is only valid for the block suffix following statement 0 at 16:76
let mut rdr = csv::Reader::from_file(f).unwrap().has_headers(false);
rdr.decode().map(|r| {
let b: Value = r.unwrap();
b.id
})
Die 2 verwendeten Lambda (die man in flat_map
und die einen in map
) nicht erfassen andere Variablen verstehe ich also nicht wirklich, warum der lokale rdr
so lange leben muss.
Nun, die decode
Funktion nimmt einen ref auf rdr
, so scheint es, map
einen Besitz ref rdr
braucht ...