简体   繁体   中英

Struggling with dangling references and suggestions for static lifetimes in Rust

Excuse my novice Rust-ing. I wrote a function to clean a file, and verified that the logic of the function appears to be fine. I then wanted to rename this function from main to a helper function. I'm aware that I could keep some of IO stuff in the main function, but for the sake of fun, let's say I want to keep all the code below in the helper function.

The code beneath will compile if we change the return type to Result<(), std::io::Error> , and modify the last line to give Ok(()) . Hovewer, this code doesn't. The compiler suggests I modify &str to &'static str , though this change doesn't appear to help things, as the compiler then says that "E0277, main can only return types that implement termination"

And at this point I start imploding under an insufficient understanding of how to avoid dangling references.

fn main() -> Result<Vec<&str>, std::io::Error> {
    let file = File::open("22names.txt")?;
    let mut buf_reader = BufReader::new(file);
    let mut contents = String::new();
    buf_reader.read_to_string(&mut contents)?;

    contents.retain(|c| c != '"');
    let v: Vec<&str> = contents.split(',').collect();

    println!("first 10 indices of v are: {:?}", &v[..10]);

    Ok(v)
}

Edit: If I modify the above, renaming main to arbitrary function f , and call f from a new main function and assign the result to a variable, let v = f() I get the following error, which results from the fact that contents is going out of scope. How do I keep contents in scope, or rather, the vector v which points to it? error[E0515]: cannot return value referencing local variable contents , where contents is referenced by v , the thing I want to return.

The main function is the entry point to your program. As this function is the first thing that gets executed no other function has called it. Your program exits after the main function has returned. The return value of the main function is used to determine the exit status of your program. Because of that no other function can use the return value of main . I suggest renaming your function.

The other error happens because you return slices of a String. Content contains the data you read from the file, while v only contains references to this data. After content goes out of scope, the memory is freed. This would lead to v containing invalid pointers. The compiler will not allow that.

You could return String instead of &str . String owns the underlying data. For that you should change the function signature to fn helper() -> Result<Vec<String>, std::io::Error> . You than would need to transform your Vec<&str> to Vec<String> . You can to that using String::from like that:

let v: Vec<String> = contents.split(',').map(String::from).collect();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM