将迭代器收集成结果?

huangapple go评论76阅读模式
英文:

How to collect an iterator into a Result?

问题

I currently have the following function:

fn filter_files<P>(input_path: P) -> Result<Vec<DirEntry>, Box<dyn error::Error>> where P: AsRef<Path> {
    fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with("_x"))
        .collect()
}

Where I am attempting to filter out files that start with "_x". I would like to have this function return the filtered Vec<DirEntry> directly instead of having to make a variable. My issue is that I cannot get the function signature correct. I am getting an error with:

error[E0277]: a value of type `Result<Vec<DirEntry>, Box<dyn std::error::Error>>` cannot be built from an iterator over elements of type DirEntry
    --> src/main.rs:18:10
     |
18   |         .collect()
     |          ^^^^^^^ value of type `Result<Vec<DirEntry>, Box<dyn std::error::Error>>` cannot be built from std::iter::Iterator<Item=DirEntry>

I am wondering what the correct signature for this function's return type should be given that the fs::read_dir(...) could return an io::Error. I know that I need to be returning a Result type. Is the usage of collect() correct, or is this an incorrect usage.

英文:

I currently have the following function:

fn filter_files&lt;P&gt;(input_path: P) -&gt; Result&lt;Vec&lt;DirEntry&gt;, Box&lt;dyn error::Error&gt;&gt; where P: AsRef&lt;Path&gt; {
    fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with(&quot;_x&quot;))
        .collect()
}

Where I am attempting to filter out files that start with _x. I would like to have this function return the filtered Vec&lt;DirEntry&gt; directly instead of having to make a variable. My issue is that I can not get the function signature correct. I am getting an error with

error[E0277]: a value of type `Result&lt;Vec&lt;DirEntry&gt;, Box&lt;dyn std::error::Error&gt;&gt;` cannot be built from an iterator over elements of type `DirEntry`
    --&gt; src/main.rs:18:10
     |
18   |         .collect()
     |          ^^^^^^^ value of type `Result&lt;Vec&lt;DirEntry&gt;, Box&lt;dyn std::error::Error&gt;&gt;` cannot be built from `std::iter::Iterator&lt;Item=DirEntry&gt;`

I am wondering what the correct signature for this function's return type should be given that the fs::read_dir(...) could return an io::Error I know that I need to be returning a Result type. Is the usage of collect() correct or is this an incorrect usage.

答案1

得分: 5

The error is a little misleading here, you can collect into a Result but only when the iterators items are of type Result&lt;A, E&gt;.

Since you know all your items exist and did not result in an error (your items are of type DirEntry not Result&lt;DirEntry, _&gt;) what you want to do instead is to wrap your known good result in a variant of Result such as Ok:

fn filter_files&lt;P&gt;(input_path: P) -&gt; std::io::Result&lt;Vec&lt;DirEntry&gt;&gt; where P: AsRef&lt;Path&gt; {
    Ok(fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with(&quot;_x&quot;))
        .collect())
}
英文:

The error is a little misleading here, you can collect into a Result but only when the iterators items are of type Result&lt;A, E&gt;.

Since you know all your items exist and did not result in an error (your items are of type DirEntry not Result&lt;DirEntry, _&gt;) what you want to do instead is to wrap your known good result in a variant of Result such as Ok:

fn filter_files&lt;P&gt;(input_path: P) -&gt; std::io::Result&lt;Vec&lt;DirEntry&gt;&gt; where P: AsRef&lt;Path&gt; {
    Ok(fs::read_dir(input_path)?
        .into_iter()
        .filter_map(|res| res.ok())
        .filter(|dir_entry| dir_entry.file_name().to_str().unwrap().starts_with(&quot;_x&quot;))
        .collect())
}

huangapple
  • 本文由 发表于 2023年3月31日 03:23:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892206.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定