我如何理解这个借值错误?建立一个 Vec<&PathBuf>
How do I understand this borrowed value error? Building a Vec<&PathBuf>
我如何理解我违反了借用检查程序的哪一部分?
因为 Rust 的标准库 walk_dir
是 listed as "unstable"(截至 2015-09-27),我想我会尝试构建自己的函数来获取目录中的所有文件并这是我自己的子目录。
我得到的只是列出目录中的文件,还没有查看子目录部分:
use std::fs::File;
use std::path::{Path,PathBuf};
fn get_files(this_path: &Path) -> Vec<&PathBuf>{
let contents = fs::read_dir(this_path).unwrap();
let mut output: Vec<&PathBuf> = Vec::new();
for path in contents {
let p = path.unwrap().path();
if fs::metadata(&p).unwrap().is_dir() {
// dunno, recursively append files to output
} else if fs::metadata(&p).unwrap().is_file() {
output.push(&p)
}
}
return output;
}
fn main() {
for f in get_files(Path::new(".")) {
println!("{}", f.display())
}
}
当我尝试 运行 此代码时,出现此错误:
src/main.rs:58:26: 58:27 error: `p` does not live long enough
src/main.rs:58 output.push(&p)
^
note: in expansion of for loop expansion
src/main.rs:53:5: 60:6 note: expansion site
src/main.rs:49:48: 63:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 49:47...
src/main.rs:49 fn get_files(this_path: &Path) -> Vec<&PathBuf>{
src/main.rs:50 let contents = fs::read_dir(this_path).unwrap();
src/main.rs:51 let mut output: Vec<&PathBuf> = Vec::new();
src/main.rs:52
src/main.rs:53 for path in contents {
src/main.rs:54 let p = path.unwrap().path();
...
src/main.rs:54:38: 60:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 54:37
src/main.rs:54 let p = path.unwrap().path();
src/main.rs:55 if fs::metadata(&p).unwrap().is_dir() {
src/main.rs:56 // dunno, recursively append files to output
src/main.rs:57 } else if fs::metadata(&p).unwrap().is_file() {
src/main.rs:58 output.push(&p)
src/main.rs:59 }
...
error: aborting due to previous error
如果我错了请纠正我,但我对 Rust 的一个很酷的特性是你必须明确声明何时对象应该在函数范围之后存在。我认为我的问题是在 let p = path.unwrap().path()
中创建的 PathBuf
在 for 循环迭代结束时被丢弃,因此 output
Vec
持有对东西不见了。
如果是这样的话:
当我做这种愚蠢的事情时,如何建立更好的直觉?
是否有更好的惯用方法来从 return 生命周期有限的资源的函数构建元素向量?
这里的直觉是:
I can't return a reference to something created inside a function, because it will be deallocated at the end of that function, making the reference invalid.
相反,你必须把那个东西搬出去。因此 Vec<PathBuf>
,Vec<&PathBuf>
的拥有变体,(因为 PathBuf
是 &PathBuf
的拥有变体)应该是你的 return 类型。
我如何理解我违反了借用检查程序的哪一部分?
因为 Rust 的标准库 walk_dir
是 listed as "unstable"(截至 2015-09-27),我想我会尝试构建自己的函数来获取目录中的所有文件并这是我自己的子目录。
我得到的只是列出目录中的文件,还没有查看子目录部分:
use std::fs::File;
use std::path::{Path,PathBuf};
fn get_files(this_path: &Path) -> Vec<&PathBuf>{
let contents = fs::read_dir(this_path).unwrap();
let mut output: Vec<&PathBuf> = Vec::new();
for path in contents {
let p = path.unwrap().path();
if fs::metadata(&p).unwrap().is_dir() {
// dunno, recursively append files to output
} else if fs::metadata(&p).unwrap().is_file() {
output.push(&p)
}
}
return output;
}
fn main() {
for f in get_files(Path::new(".")) {
println!("{}", f.display())
}
}
当我尝试 运行 此代码时,出现此错误:
src/main.rs:58:26: 58:27 error: `p` does not live long enough
src/main.rs:58 output.push(&p)
^
note: in expansion of for loop expansion
src/main.rs:53:5: 60:6 note: expansion site
src/main.rs:49:48: 63:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 49:47...
src/main.rs:49 fn get_files(this_path: &Path) -> Vec<&PathBuf>{
src/main.rs:50 let contents = fs::read_dir(this_path).unwrap();
src/main.rs:51 let mut output: Vec<&PathBuf> = Vec::new();
src/main.rs:52
src/main.rs:53 for path in contents {
src/main.rs:54 let p = path.unwrap().path();
...
src/main.rs:54:38: 60:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 54:37
src/main.rs:54 let p = path.unwrap().path();
src/main.rs:55 if fs::metadata(&p).unwrap().is_dir() {
src/main.rs:56 // dunno, recursively append files to output
src/main.rs:57 } else if fs::metadata(&p).unwrap().is_file() {
src/main.rs:58 output.push(&p)
src/main.rs:59 }
...
error: aborting due to previous error
如果我错了请纠正我,但我对 Rust 的一个很酷的特性是你必须明确声明何时对象应该在函数范围之后存在。我认为我的问题是在 let p = path.unwrap().path()
中创建的 PathBuf
在 for 循环迭代结束时被丢弃,因此 output
Vec
持有对东西不见了。
如果是这样的话:
当我做这种愚蠢的事情时,如何建立更好的直觉?
是否有更好的惯用方法来从 return 生命周期有限的资源的函数构建元素向量?
这里的直觉是:
I can't return a reference to something created inside a function, because it will be deallocated at the end of that function, making the reference invalid.
相反,你必须把那个东西搬出去。因此 Vec<PathBuf>
,Vec<&PathBuf>
的拥有变体,(因为 PathBuf
是 &PathBuf
的拥有变体)应该是你的 return 类型。