我是Rust的新手。我正在尝试构建一个JSON对象,其中键是文件名,值是文件内容。
到目前为止,我有:
use std::fs;
use std::io;
use std::env;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
fn main() {
make_json();
}
fn make_json() -> io::Result<()> {
let mut modules = HashMap::new();
let mut dir = env::current_dir().unwrap();
let mut read_dir = fs::read_dir(dir);
for entry in try!(read_dir) {
let entry = try!(entry);
let file_name = entry.path().file_name().unwrap().to_string_lossy();
modules.insert(file_name, "");
}
Ok(())
}
当我去编译它时,我得到了
src/main.rs:19:25: 19:37 error: borrowed value does not live long enough
src/main.rs:19 let file_name = entry.path().file_name().unwrap().to_string_lossy();
^~~~~~~~~~~~
note: in expansion of for loop expansion
src/main.rs:17:5: 21:6 note: expansion site
src/main.rs:13:38: 23:2 note: reference must be valid for the block suffix following statement 0 at 13:37...
src/main.rs:13 let mut modules = HashMap::new();
src/main.rs:14 let mut dir = env::current_dir().unwrap();
src/main.rs:15 let mut read_dir = fs::read_dir(dir);
src/main.rs:16
src/main.rs:17 for entry in try!(read_dir) {
src/main.rs:18 let entry = try!(entry);
...
src/main.rs:19:9: 19:77 note: ...but borrowed value is only valid for the statement at 19:8
src/main.rs:19 let file_name = entry.path().file_name().unwrap().to_string_lossy();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:19:9: 19:77 help: consider using a `let` binding to increase its lifetime
src/main.rs:19 let file_name = entry.path().file_name().unwrap().to_string_lossy();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
我明白这个错误告诉我的是什么; entry是在for
循环的范围内定义的,因此如果我将它存储到HashMap
,它将不再是有效的内存,因为内存中的位置已经被释放。我知道了。
我没有得到的是,如何在不使用某种闭包的情况下访问DirEntry
中的read_dir
,因为我需要在我检索它们的任何闭包之外的信息。
我遇到的一切都无法帮助我。
答案 0 :(得分:2)
DirEntry.path()
返回PathBuf
,即'static
(即它不包含非静态引用,并且是完全独立的对象)。 它是问题所在。
PathBuf.file_name()
返回Option<&OsStr>
,对该对象的引用,以及OsStr.to_string_lossy()
returns Cow<str>
。最后请注意,不是 'static
;随着生命周期的恢复,这是fn to_string_lossy<'a>(&'a self) -> Cow<'a, str>
。这是为了提高效率,因为如果路径是合法的UTF-8,则无需创建全新的字符串(String
),它可以将其保留为字符串切片(&str
)。 (因为Cow<'a, str>
就是这样的:填充了泛型的变体是Owned(String)
和Borrowed(&'a str)
。)
您需要在此位置将Cow<str>
变为String
。这是通过into_owned
method of Cow<T>
完成的。
这一行代码就这样成了:
let file_name = entry.path().file_name().unwrap().to_string_lossy().into_owned();