首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何跳过导致生锈执行的错误?

如何跳过导致生锈执行的错误?
EN

Stack Overflow用户
提问于 2020-10-04 07:17:33
回答 2查看 196关注 0票数 0

为了学习生锈,我正在从头开始编写一个递归目录遍历程序。

代码语言:javascript
复制
use std::fs;

fn main() {
    let paths = fs::read_dir("/").unwrap();
    for path in paths {
        println!("First: {:?}", path);
        let sub_paths = fs::read_dir(path.unwrap().path());
        for sub_path in sub_paths.unwrap() {
            println!("  Second: {:?}", sub_path);
        }
    }
}

这段代码的问题是,如果一个文件夹没有正确的访问权限,或者它是一个文件,那么它就存在执行。如何跳过导致类似于try...except的文件夹或文件的错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-04 08:28:06

备选案文1

一个可能的解决方案是使用matching。然后Ok(v)分支将类似于try块,而Err(e)分支将类似于catch块。最后,它看起来可能是(游乐场):

代码语言:javascript
复制
use std::fs;

fn main() {
    match fs::read_dir("/") {
        Ok(may_be_entries_vec) => {
            for may_be_entry in may_be_entries_vec {
                println!("First: {:?}", may_be_entry);
                
                match may_be_entry {
                    Ok(entry) => {
                        let path = entry.path();
                        match fs::read_dir(&path) {
                            Ok(may_be_sub_entry_vec) => {
                                for may_be_sub_entry in may_be_sub_entry_vec {
                                    println!("  Second: {:?}", may_be_sub_entry);
                                }
                            },
                            Err(e) => {
                                eprintln!(
                                    "Couldn't obtain {:?} content. The error is {:?}",
                                    path,
                                    e
                                )
                            },
                        }
                    },
                    Err(_e) => {
                        // Ex: eprintln!("Entry is an error:{:?}", _e);
                    },
                }
            }
        },
        Err(e) => {
            eprintln!("Couldn't obtain \"/\" content. The error is {:?}.", e);
        },
    }
}

选项2

或者您可以跳过所有错误(这不是一个好选项,但仍然是一个选项) (游乐场):

代码语言:javascript
复制
use std::fs;

fn main() {
    if let Ok(entries_vec) = fs::read_dir("/") {
        for may_be_entry in entries_vec {
            println!("First: {:?}", may_be_entry);
            
            if let Ok(entry) = may_be_entry {
                if let Ok(sub_entry_vec) = fs::read_dir(entry.path()) {
                    for may_be_sub_entry in sub_entry_vec {
                        println!("  Second: {:?}", may_be_sub_entry);
                    }
                }
            }
        }
    }
}

选项3

或者你可能更喜欢类似功能的风格。记住,or_else的那种用途可能是值得怀疑的。如果要跳过所有错误,可以删除所有or_else调用。(游乐场):

代码语言:javascript
复制
use std::fs;

fn main() {
    fs::read_dir("/")
        .or_else(|e| {
            eprintln!("Couldn't obtain '/' content. The error is {:?}.", e); 
            Err(e)
        })
        .iter_mut()
        .flat_map(|i| i)
        .for_each(|may_be_entry|{
            println!("First: {:?}", may_be_entry);
            
            may_be_entry
            .or_else(|e| {
                // Ex: eprintln!("Entry is an error:{:?}", e);
                Err(e)
            })
            .iter()
            .map(|e| e.path())
            .map(|path| (fs::read_dir(&path), path))
            .for_each(|(read_dir_result, path)|{
                read_dir_result
                    .or_else(|e| {
                        eprintln!(
                            "Couldn't obtain '{:?}' content. The error is {:?}.",
                            path,
                            e
                        ); 
                        Err(e)
                    })
                    .iter_mut()
                    .flat_map(|i| i)
                    .for_each(|may_be_subentry|{
                        println!("   Second: {:?}", may_be_subentry);
                    });
            });
        });
}

另一种可能的方法是使用运算符,从一种错误到另一种错误有一些微妙的传递。但我觉得这太过分了。

票数 1
EN

Stack Overflow用户

发布于 2020-10-04 07:24:58

不要使用unwrap,除非您确实确定值在那里。相反,match是一个Option,结果与它的两种可能性相反:Some(value)None

Result与其两种可能性相匹配:Ok(T)Err(E)

变体枚举

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64192056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档