我想知道当前目录中是否存在foo
文件夹,所以我编写了一个函数来执行此操作:
use std::env;
use std::fs;
use std::io;
fn does_folder_foo_exist_in_current_directory() -> Result<bool, io::Error> {
let cur_path_buf = env::current_dir()?;
let cur_dir = cur_path_buf.as_path();
Ok(fs::read_dir(cur_dir)?.find(|ref x| {
let x = x.unwrap();
x.file_type().unwrap().is_dir() && x.file_name().to_str().unwrap() == "foo"
}).is_some())
}
但是,编译器说我不能放弃借来的内容:let x = x.unwrap();
。
为什么这会从我ref x
开始借用内容?
答案 0 :(得分:1)
ref
用于构造引用。如果模式x
具有类型T
,则模式ref x
将具有类型&T
。但是,移出引用是无效的,所以你绝对不想构建引用! (unwrap
按值获取self
,这就是代码首先尝试移动的原因。)
这里,闭包上的参数类型是一个引用,因为这是Iterator::find
想要作为参数传递的内容。如果您想解构引用,则需要使用&
。但是,如果您在此处编写模式&x
,则仍会收到错误cannot move out of borrowed content
,但这次直接在&x
上。
我们可以做些什么呢? DirEntry
未实现Clone
,因此我们无法克隆x
(&std::io::Result<DirEntry>
)。相反,我们可以将&Result<DirEntry>
变成Result<&DirEntry>
。标准库中有一种方法可以做到这一点:as_ref
。
fn does_folder_foo_exist_in_current_directory() -> Result<bool, io::Error> {
let cur_path_buf = env::current_dir()?;
let cur_dir = cur_path_buf.as_path();
Ok(fs::read_dir(cur_dir)?.find(|x| {
let x = x.as_ref().unwrap();
x.file_type().unwrap().is_dir() && x.file_name().to_str().unwrap() == "foo"
}).is_some())
}
顺便说一句,您可以使用any(...)
,而不是find(...).is_some()
,而https://pastebin.com/zymW2XZw更短,效率更高一些。 any
也将每个迭代值的所有权传递给闭包,因此我们实际上不需要使用as_ref
!
fn does_folder_foo_exist_in_current_directory() -> Result<bool, io::Error> {
let cur_path_buf = env::current_dir()?;
let cur_dir = cur_path_buf.as_path();
Ok(fs::read_dir(cur_dir)?.any(|x| {
let x = x.unwrap();
x.file_type().unwrap().is_dir() && x.file_name().to_str().unwrap() == "foo"
}))
}
答案 1 :(得分:0)
没有理由迭代目录中的所有条目以检查是否存在单个项目。只需检查具体项目:
use std::{env, fs, io};
fn does_folder_foo_exist_in_current_directory() -> io::Result<bool> {
let mut path = env::current_dir()?;
path.push("foo");
let metadata = fs::metadata(path)?;
Ok(metadata.is_dir())
}