在 Rust 中使用 std::fs::read_dir 作为迭代器

问题描述 投票:0回答:1

我是 Rust 新手(大约一个月),这是我第一次在这个平台上提问。 请原谅我犯了一些错误。 现在,我正在尝试制作一个复制整个目录的保存系统。 看起来像这样:

[文件层次结构]

文件

  • 保存
  • 日志
  • write_log(我正在做的事情)

[主要.rs]

use std::fs::{copy,create_dir,read_dir};
use std::path::{Path,PathBuf};

fn copy_dir(cp_path: &Path,wr_path: &Path){
    // if cp_path is a directory, repeat self to every components
    if cp_path.is_dir(){
        create_dir(&wr_path);
        for each_file in read_dir(cp_path) {
            //dynamic path to edit
            let mut pathbuf = PathBuf::new();
            pathbuf.push(&wr_path);
            match each_file {
                Ok(i) => {
                    let file_path = i.path().as_path();
                    match file_path.file_name(){
                        Some(name) =>{
                            let filename = Path::new(&name);
                            pathbuf.push(&filename);
                            //recurse
                            copy_dir(&file_path,&pathbuf.as_path());
                        }
                        None => {
                            //create an empty dir if name isn't valid
                            pathbuf.push(&Path::new("N/A"));
                            create_dir(pathbuf.as_path());
                        }
                    }
                }
                Err(e) => {
                    panic!();
                }
            }
        }
    }else{  copy(&cp_path,&wr_path); }
}

fn main() {
    let copy_path = Path::new("tosave");
    let write_path = Path::new("logs/foo");
    copy_dir(&copy_path,&write_path);
}

当我尝试编译代码时,出现错误。

error[E0308]: mismatched types
  --> src/main.rs:12:17
   |
11 |             match each_file {
   |                   --------- this expression has type `ReadDir`
12 |                 Ok(i) => {
   |                 ^^^^^ expected `ReadDir`, found `Result<_, _>`
   |
   = note: expected struct `ReadDir`
                found enum `Result<_, _>

我期望每个文件的类型是“Option”。 但“for ~ in”循环似乎无法正常运行, 它以某种方式给了each_file一个

ReadDir
。 请帮我解决这个问题。

(我参考的文档)

https://doc.rust-lang.org/std/fs/fn.read_dir.html https://doc.rust-lang.org/std/fs/struct.ReadDir.html

file rust
1个回答
0
投票

如果我们删除循环体,编译器可以提供帮助:

fn copy_dir(cp_path: &Path, wr_path: &Path) {
    // if cp_path is a directory, repeat self to every components
    if cp_path.is_dir() {
        create_dir(&wr_path);
        for each_file in read_dir(cp_path) {
        }
    } else {
        copy(&cp_path, &wr_path);
    }
}
warning: for loop over a `Result`. This is more readably written as an `if let` statement
 --> src/main.rs:8:26
  |
8 |         for each_file in read_dir(cp_path) {
  |                          ^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(for_loops_over_fallibles)]` on by default
help: to check pattern in a loop use `while let`
  |
8 |         while let Ok(each_file) = read_dir(cp_path) {
  |         ~~~~~~~~~~~~~         ~~~
help: consider using `if let` to clear intent
  |
8 |         if let Ok(each_file) = read_dir(cp_path) {

游乐场

发生的情况是

read_dir()
返回
Result<ReadDir, std::io::Error>
。您打算迭代
ReadDir
(这是
Result<DirEntry, std::io::Error>
上的迭代器,但实际上是在
Result
上迭代。这不是直接错误,因为
Result
实现了
IntoIterator
- 它产生
Ok如果 
Ok
 则为 
值,如果
Err
则为空,这对于例如通过
flatten()
忽略迭代器中的错误很有用。

您需要处理

Result

,例如通过
unwrap()
ing它。

© www.soinside.com 2019 - 2024. All rights reserved.