gpt4 book ai didi

rust - 读取一级目录结构

转载 作者:行者123 更新时间:2023-11-29 08:22:26 32 4
gpt4 key购买 nike

我正在尝试使用 Rust 列出目录中的所有目录(不是递归地)。我主要遵循示例代码 from the read_dir文档,但我试图让它更简单,因为我提前知道目录是什么,我不需要递归。

我把它归结为:

for entry in read_dir(Path::new("known-directory")) {
let path = entry.path();

if path.is_dir() {
print!("{}", entry);
}
}

这行不通,因为我收到了投诉

no method named `path` found for type `std::fs::ReadDir` in the current scope

看起来 for 实际上并没有遍历 ReadDir 的条目。

我也尝试过 try!(read_dir(Path::new("DefinitelyTyped"))) 类似于文档中的内容,但这会产生

expected (), found enum `std::result::Result`

使用 let entry = try!(entry) 也不起作用。

最终我想将这些目录条目推送到一个数组,对其进行排序,然后对其进行 JSON 字符串化,但当然首先我必须能够正确地遍历这些条目。我该怎么做?

版本:rustc 1.13.0
运行:cargo 0.13.0

最佳答案

让我们一起阅读编译器错误信息!

error: no method named `path` found for type `std::fs::ReadDir` in the current scope
--> src/main.rs:5:26
|
5 | let path = entry.path();
| ^^^^

这意味着 entry 的类型是 ReadDir,但这是如何发生的呢?我们应该迭代 ReadDir!

如果我们看一下 documentation for read_dir , 我们可以看到它返回了一个 Result:

pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>

这意味着读取目录的过程可能会失败,这是完全可信的——如果目录不存在怎么办?但是,提供的代码不处理该错误。而是将 Result 传递给 for 循环。 for 循环通过调用 IntoIterator 来工作,Result 实现它,产生 Ok 情况或根本没有。 Option 有类似的实现。

因此,您在代码中添加了 try!...

for entry in try!(fs::read_dir("/etc"))
error[E0308]: mismatched types
--> src/main.rs:4:18
|
4 | for entry in try!(fs::read_dir("/etc")) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
|
= note: expected type `()`
= note: found type `std::result::Result<_, _>`
= note: this error originates in a macro outside of the current crate

一直discussed previously并在 documentation for try! 中提到:

Because of the early return, try! can only be used in functions that return Result.

您必须以某种方式处理错误,无论出于何种原因,您当前的函数都声明它不会失败 — 它不会返回Result!相反,让我们通过在调用中添加 expect 来结束整个程序:

for entry in fs::read_dir("/etc").expect("I told you this directory exists")

(有些人使用unwrap,但我会始终提倡expect,因为它更有可能为穷人提供有用的信息经历最终失败的灵魂)

error: no method named `path` found for type `std::result::Result<std::fs::DirEntry, std::io::Error>` in the current scope
--> src/main.rs:5:26
|
5 | let path = entry.path();
| ^^^^

是的,甚至还有更多可能的失败案例。具体来说,由于某种原因,读取每个条目可能会失败。这就是为什么 ReadDir 迭代器说

type Item = Result<DirEntry>

同样,您的函数仍然声明它不会失败,因此我们不得不再次 panic :

let entry = entry.expect("I couldn't read something inside the directory");
error[E0277]: the trait bound `std::fs::DirEntry: std::fmt::Display` is not satisfied
--> src/main.rs:9:26
|
9 | print!("{}", entry);
| ^^^^^ trait `std::fs::DirEntry: std::fmt::Display` not satisfied
|
= note: `std::fs::DirEntry` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
= note: required by `std::fmt::Display::fmt`

如错误消息中所述,将 {} 更改为 {:?},因为 DirEntry 没有正确的格式化方式终端用户。程序员可以处理调试格式。


use std::fs;

fn main() {
for entry in fs::read_dir("/etc").expect("I told you this directory exists") {
let entry = entry.expect("I couldn't read something inside the directory");
let path = entry.path();

if path.is_dir() {
print!("{:?}", entry);
}
}
}

我强烈建议重新阅读 error handling chapterThe Rust Programming Language .我还提倡基本上记住为 Result 实现的方法和特征。和 Option ,将它们视为 Rust 体验的核心。

这是一个从 main 返回错误并使用 try 运算符 (?) 的版本:

use std::{error::Error, fs};

fn main() -> Result<(), Box<dyn Error>> {
for entry in fs::read_dir("/etc")? {
let entry = entry?;
let path = entry.path();

if path.is_dir() {
print!("{:?}", entry);
}
}

Ok(())
}

关于rust - 读取一级目录结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40551411/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com