英文:
creates temporary which is freed while still in use when reading path of DirEntry
问题
I'm trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:
I don't understand, how in the following code, the e.path
statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
match path {
Ok(e) => {
let fullPath = e.path();
let extension = e
.path()
.extension()
.expect("Error getting extension")
.to_str()
.expect("Could not convert extensions to string");
println!("{}", extension)
}
_ => {}
}
}
I tried numerous things and stuff like .path().metadata()
does not throw this error. Only when in combination with extension()
this seems to be happening? It's really confusing me, how a task this simple becomes so complex.
英文:
I'm trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:
I don't understand, how in the following code, the e.path
statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
match path {
Ok(e) => {
let fullPath = e.path();
let extension = e
.path()
.extension()
.expect("Error getting extension")
.to_str()
.expect("Could not convert extensions to string");
println!("{}", extension)
}
_ => {}
}
I tried numerous things and stuff like .path().metadata()
does not throw this error. Only when in combination with extension()
this seems to be happening? It's really confusing me, how a task this simple becomes so complex.
答案1
得分: 1
DirEntry::path()
返回一个 PathBuf
,PathBuf::extension()
返回一个 Option<&OsStr>
。正如你所见,OsStr
是从原始的 PathBuf
/ Path
中借用的。问题是,你试图将扩展名绑定到一个变量,但你没有分配从中借用的 PathBuf
给一个变量。
因此编译器正确地指出 PathBuf
是临时的,并且会在 let extension = ...
语句之后被丢弃,因此 extension
不能继续指向它。
你已经做对了 - 将那个 PathBuf
的另一个副本赋值给 fullPath
。所以你可以直接从中借用扩展名。
这里是一个完全独立的解决方案:
use std::fs;
fn main() {
let folder = "./src";
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
if let Ok(e) = path {
let full_path = e.path(); // 这将至少存活和 `extension` 一样长的时间,所以从中借用是可以的。
let extension = full_path
.extension()
.expect("获取扩展名时出错")
.to_str()
.expect("无法将扩展名转换为字符串");
println!("{}", extension)
}
}
}
英文:
DirEntry::path()
returns a PathBuf
, and PathBuf::extension()
returns an Option<&OsStr>
. As you can see, the OsStr
is borrowed from the original PathBuf
/ Path
. The problem is, you're trying to bind the extension to a variable, but you do not assign the PathBuf
that is borrowed from to a variable as well.
So the compiler is correct in saying that the PathBuf
is temporary, and will be dropped after your let extension = ...
statement, and thus extension
can not keep pointing to it.
You're already doing the right thing - assigning another copy of that PathBuf
to fullPath
. So you can just borrow the extension from it.
Here's a fully self-contained solution:
use std::fs;
fn main() {
let folder = "./src";
let paths = fs::read_dir(&folder).unwrap();
for path in paths {
if let Ok(e) = path {
let full_path = e.path(); // This will live at least as long as `extension`, so
// borrowing from it is fine.
let extension = full_path
.extension()
.expect("Error getting extension")
.to_str()
.expect("Could not convert extensions to string");
println!("{}", extension)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论