I can't figure out the problem with my code. I'm trying to make a CLI app to learn rust by doing a project and I keep getting error E0515
Here is my code:
use std::path::Display;
use std::fs;
fn read_file(path: &str) -> String {
fs::read_to_string(path)
.expect("Should have been able to read the file")
}
fn list_dir(path: &str) -> Vec<Display>{
let paths = fs::read_dir(path).unwrap();
let mut dirs: Vec<Display> = vec![];
for path in paths {
dirs.push(path.unwrap().path().display());
}
dirs
}
fn main() {
println!("{}",list_dir("C:").len())
}
The compiler tells me that i am returning a value that is referencing data owned by list_dir
function:
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:15:5
|
13 | dirs.push(path.unwrap().path().display());
| -------------------- temporary value created here
14 | }
15 | dirs
| ^^^^ returns a value referencing data owned by the current function
I tried some ways to change the return type of the function but none of them worked.
Can someone tell me what I'm doing wrong?
std::path::Display borrows a Path
. You can tell it because it is generic over a lifetime (Display<'a>
). However your problem is deeper. If you try doing something like this:
fn list_dir(path: &str) -> () {
let paths = fs::read_dir(path).unwrap();
let mut dirs: Vec<Display> = vec![];
for path in paths {
dirs.push(path.unwrap().path().display());
}
}
This will still fail to compile and you will get the following error:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:13:19
|
13 | dirs.push(path.unwrap().path().display());
| ----------^^^^^^^^^^^^^^^^^^^^------------ temporary value is freed at the end of this statement
| | |
| | creates a temporary value which is freed while still in use
| borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
The problem here is that fs::read_dir
returns an iterator, which yields ReadDir structs, from which you can take a PathBuf (an owned representation of OS path) using method ReadDir::path.
However you cannot store references to those PathBuf
s, because they will be dropped on the next iteration.
Now you have to ask yourself, what do you want to do? If you wish to return a vector of those paths (which I guess is what you want), just return a Vec<PathBuf>
. If you want to use std::path::Display
implementation to get utf-8 representation of paths return a vector of String
s and simply call to_string
inside your push
call.