【问题标题】:Returning Error Enumeration with an Arbitrary Variable使用任意变量返回错误枚举
【发布时间】:2016-04-11 15:33:47
【问题描述】:

我在 Rust 中有一个使用 try! 的函数,它尝试递归地收集目录中的所有文件并将它们插入到向量中。因为函数使用try! 来检查错误,编译器似乎期望函数返回io::Result,并且不允许我包含向量,因为try! 宏只返回结果。我需要返回向量。

代码如下:

mod os{
    use std::io;
    use std::fs::{self, DirEntry};
    //use std::fs;
    use std::path::Path;
    // one possible implementation of walking a directory only visiting files
    pub fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> (io::Result<()>,Vec<String>) {
        let mut filevec: Vec<String> = Vec::new();
        if try!(fs::metadata(dir)).is_dir() {
            for entry in try!(fs::read_dir(dir)) {
                let entry = try!(entry);
                if try!(fs::metadata(entry.path())).is_dir() {
                    try!(visit_dirs(&entry.path(), cb));
                } else {
                    cb(&entry);
                }
            }
        }
        (Ok(()),filevec)

    }
fn push_path_to_vec(p:&DirEntry,v:Vec<String>){
    v.push(p.path().to_str().unwrap().to_string());
}}

这是错误:

<std macros>:5:8: 6:42 error: mismatched types:
 expected `(core::result::Result<(), std::io::error::Error>, collections::vec::Vec<collections::string::String>)`
    found `core::result::Result<_, _>`
(expected tuple,
    found enum `core::result::Result`) [E0308]

我想知道是否有任何我错过的惯用方法。

【问题讨论】:

  • 您可能需要以下功能:pub fn visit_dirs(dir: &amp;Path, cb: &amp;Fn(&amp;DirEntry)) -&gt; io::Result&lt;Vec&lt;String&gt;&gt;。注意Vec&lt;String&gt; 现在是如何包含在结果中的。
  • 顺便说一句,我认为你的问题的标题并不完全准确,因为它不是关于在函数中返回多个值,对吧?
  • 可能不会。我会改的。

标签: vector error-handling rust


【解决方案1】:

visit_dirs 的返回类型错误。该函数应该返回一个Result,但现在它返回一个元组。由于try! 仅适用于返回Result 的函数,因此您的代码无法编译。您可以更改visit_dirs 的返回值来修复它:

pub fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<Vec<String>>

新定义意味着Vec&lt;String&gt; 将在成功后存储在Result 中。通过一些小的调整,代码被编译器接受(见下文)

mod os{
    use std::io;
    use std::fs::{self, DirEntry};
    //use std::fs;
    use std::path::Path;
    // one possible implementation of walking a directory only visiting files
    pub fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<Vec<String>> {
        let mut filevec: Vec<String> = Vec::new();
        if try!(fs::metadata(dir)).is_dir() {
            for entry in try!(fs::read_dir(dir)) {
                let entry = try!(entry);
                if try!(fs::metadata(entry.path())).is_dir() {
                    try!(visit_dirs(&entry.path(), cb));
                } else {
                    cb(&entry);
                }
            }
        }
        Ok(filevec)
    }
fn push_path_to_vec(p:&DirEntry,mut v:Vec<String>){
    v.push(p.path().to_str().unwrap().to_string());
}}

【讨论】:

  • 太好了,谢谢。这就说得通了。您之前的评论帮助我独立到达那里(嗯..有点独立),但确认很好。
  • 乐于助人。你在关注The Book 学习 Rust 吗?
  • 是的,我是。没有完全学完,但我发现这门语言非常引人注目。
猜你喜欢
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 2015-10-04
  • 2019-05-12
  • 1970-01-01
相关资源
最近更新 更多