[英]Checking if folder exists in directory
I want to know if the folder foo
exists in my current directory, so I wrote a function to do so: 我想知道文件夹
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())
}
However, the compiler says that I cannot move out of borrowed content here: let x = x.unwrap();
但是,编译器说我不能在这里移出借用的内容:
let x = x.unwrap();
. 。
Why is this moving out of borrowed content since I ref x
? 自从我
ref x
以来,为什么这会移出借用的内容?
ref
in patterns is used to construct a reference. 模式中的
ref
用于构造参考。 If the pattern x
would have type T
, then the pattern ref x
will have type &T
instead. 如果模式
x
类型为T
,则模式ref x
类型为&T
。 However, it's not valid to move out of a reference, so you definitely don't want to construct a reference! 但是,移出引用是无效的,因此您绝对不想构造引用! (
unwrap
takes self
by value, which is why the code is trying to do a move in the first place.) (
unwrap
需要按值进行self
,因此代码首先尝试进行移动。)
Here, the type of the parameter on the closure is a reference, because that's what Iterator::find
wants to pass as an argument. 在这里,闭包上的参数类型是一个引用,因为这就是
Iterator::find
想要作为参数传递的内容。 If you want to deconstruct a reference, you want to use &
instead. 如果要解构引用,请改用
&
。 However, if you write the pattern &x
here, you'll still get the error cannot move out of borrowed content
, but this time directly on &x
. 但是,如果您在此处编写模式
&x
,您仍然会得到cannot move out of borrowed content
的错误,但这一次直接在&x
。
What can we do instead? 我们该怎么办呢?
DirEntry
doesn't implement Clone
, therefore we can't clone x
(which is an &std::io::Result<DirEntry>
). DirEntry
没有实现Clone
,因此我们不能克隆x
(这是&std::io::Result<DirEntry>
)。 Instead, we could turn the &Result<DirEntry>
into a Result<&DirEntry>
. 相反,我们可以将
&Result<DirEntry>
转换为Result<&DirEntry>
。 There's a method in the standard library to do just that: as_ref
. 标准库中有一个方法可以做到这一点:
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())
}
By the way, instead of doing find(...).is_some()
, you can use any(...)
, which is shorter and perhaps slightly more efficient. 顺便说一句,您可以使用
any(...)
而不是执行find(...).is_some()
any(...)
,它更短并且效率可能更高。 any
also passes ownership of each iterated value to the closure, so we don't actually need to use as_ref
with it! 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"
}))
}
There's no reason to iterate over all the entries in a directory to check if a single item exists. 没有理由遍历目录中的所有条目以检查是否存在单个项目。 Just check for the specific item:
只需检查特定项目:
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())
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.