Noob Question: Extending local variable lifetime


#1

Hi all!

Thank you for your time; I promise I’ve done my best to find the answer to this question on my own.
I’m trying to write a super simple function to return an iterator over a buffer.

fn read_file<'a>(filename: String) -> Chars<'a> {
    let file = File::open(filename).expect("failed to open file");
    let mut reader = BufReader::new(file);
    let mut buf = String::new();
    reader.read_to_string(&mut buf);
    buf.chars()
}

I realize that the problem is that my string buf is stack allocated and needs a lifetime of 'a. However, I have no idea how to make this happen. I’ve tried things like boxing my iterator, boxing my string, and calling clone. However, I’m obviously missing something fundamental. I’ve read RustByExample and the Rust book, and I’m reading Programming Rust (Blandy and Orendorff).

Thank you for your time and attention. I appreciate the help!


#2

You don’t. You don’t tell the compiler what the lifetime of something is; it’s lifetime is what the compiler says it is. You don’t “extend” local variable lifetimes, period.

First thing you can do is: don’t return Chars, return the String.

Second thing: take buf as a parameter. That way, the lifetime of buf is based on what was passed into it, and can thus live longer than the function does.

As an aside: pretty much any time you have a non-'static lifetime which only appears in the return type of a function, that isn’t going to work.


#3

Thank you! Quick follow up:

Why does returning the String work but returning the Chars not work?


#4

Because the String is owned, the Chars is borrowed. A borrow cannot outlive the thing it borrows.


#5

Ok, I think that makes sense to me. I appreciate your response.