use std::fs::File;
use std::io::{Write, BufReader, BufRead};
use std::io;
use std::collections::HashMap;
fn main() {
let x = run();
println!("{:#?}", x);
}
fn run() -> HashMap<&str, f64> {
let path = "lines.txt";
let mut output = File::create(path)?;
write!(output, "year,GDP,passengars
2011,6.2,26.3
2012,6.5,26.65
2013,5.48,25.03
2014,6.54,26.01
2015,7.18,27.9
2016,7.93,30.47")?;
let input = File::open(path)?;
let buffered = BufReader::new(input);
let mut gdp_sales: HashMap<&str, f64> = HashMap::new();
for line in buffered.lines().skip(1) {
let record = line?;
let data: Vec<&str> = record.split(",").collect();
gdp_sales.insert(data[1], data[2].parse::<f64>().unwrap());
println!("{}", data[0].parse::<f64>().unwrap());
}
gdp_sales
}
And the error I got is:
error[E0597]: `record` does not live long enough
--> src/main.rs:31:31
|
31 | let data: Vec<&str> = record.split(",").collect();
| ^^^^^^ borrowed value does not live long enough
32 | gdp_sales.insert(data[1], data[2].parse::<f64>().unwrap());
| --------- borrow used here, in later iteration of loop
33 | println!("{}", data[0].parse::<f64>().unwrap());
34 | }
| - `record` dropped here while still borrowed
BufReader::lines(self) creates an iterator that yields Result<String>, therefore because it consumes self and returns owned strings, it is not possible for data to live. Let me annotate your code a bit to demonstrate:
let input = File::open(path)?;
let buffered = BufReader::new(input);
let mut gdp_sales: HashMap<&str, f64> = HashMap::new(); //Lives for 'b
for line in buffered.lines().skip(1) { //Line is owned, we'll give it a lifetime 'a
let record = line?;
let data: Vec<&'a str> = record.split(",").collect();
gdp_sales.insert(data[1], data[2].parse::<f64>().unwrap());
println!("{}", data[0].parse::<f64>().unwrap());
} //'a ends here and `line` is now dropped, and it's a `String`, not a reference
//Error, your 'a data is now in 'b hashmap!
That means "all &str that I return are contained in something", but since () doesn't contain strings, there are no strings that you could possibly return this way.
Please realize that this still wouldn't work, as I explained in the first half of my previous post. Piece by piece, the data will be dropped at the end of every iteration, because line is dropped, and therefore its contents are as well.