Cannot return value referencing temporary value

impl CSV {
    pub fn read(&self) -> Result<Lines, Box<dyn std::error::Error + 'static>> {
        Ok(std::fs::read_to_string(self.file_address.as_ref())?.lines())
    }
}

Hi I met some problems with this fn returning, can somebody help me with it? thanks

Lines borrows from the string, so you can't return it from the function which creates the string. You have to collect it into the owned storage, like Vec.

Hi String is also just vector right? does that mean I can only return a string?

You can't only return a String, but here returning one is probably the best idea.

Your code is roughly equivalent to:

impl CSV {
    pub fn read(&self) -> Result<Lines, Box<dyn std::error::Error + 'static>> {
        // creates a temporary string
        let tmp = std::fs::read_to_string(self.file_address.as_ref())?; 
        // is looking at the string
        let lines = Lines::new(&tmp);
        // the string is destroyed
        drop(tmp);
        // lines is trying to read a string that doesn't exist
        Ok(lines)
    }
}

Unfortunately you can't return both String and Lines together, since Rust doesn't support self-referential structures. You have to collect lines into Vec<String>.

Hi kornel, thanks for the explaination. I put the string in the struct so I return the Lines right now.

BTW, there's another way. io::Lines owns its io::Read implementation, so it can be returned, because it doesn't need to reference a variable:

pub fn read(path: &Path) -> io::Result<io::Lines<io::BufReader<File>>> {
    Ok(io::BufReader::new(File::open(path)?).lines())
}
3 Likes