检查目录中是否存在文件夹

时间:2017-12-09 04:21:46

标签: rust directory

我想知道当前目录中是否存在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开始借用内容?

2 个答案:

答案 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())
}