如何在Rust中将返回Result的函数应用于HashSet的每个元素?[重复]

cyvaqqii  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(122)

此问题在此处已有答案

How do I stop iteration and return an error when Iterator::map returns a Result::Err?(4个答案)
6天前关闭。
我有一个类型定义如下:

pub struct State<T: Clone + Eq> {
    pub db: HashSet<T>,
}

我有一个函数,看起来像下面这样:

fn check(&self) -> Result<(), Error> {
   self.db.iter().for_each(|elem| elem.check());
   Ok(())
}

因此,我想为HashSet中的每个元素调用check函数。我只是想确保所有返回()或有一些Error抛出。上面抛出错误,因为它期望()作为elem.check()的输出,但它返回Result。在Rust中正确的处理方法是什么?

s4n0splo

s4n0splo1#

(): FromIterator<()>开始,将多个Result<(), E>短路“收集”到另一个Result<(), E>实际上是非常符合人体工程学的:

use std::collections::HashSet;
pub struct State<T: Clone + Eq> {
    pub db: HashSet<T>,
}

/// Checks for equality to 0
fn check(x: i32) -> Result<String, String> {
    if x == 0 {
        Ok("yay, got 0".into())
    } else {
        Err(format!("whoops, got {} != 0", x))
    }
}

impl State<i32> {
    fn check(&self) -> Result<(), String> {
        self.db
            .iter()
            .map(|elem| check(*elem).map(|_| ()))
            .collect()
    }
}

fn main() {
    let state1 = State {
        db: [0, 0, 0].into(),
    };
    let state2 = State {
        db: [0, 1, 2].into(),
    };

    println!("{:?}, {:?}", state1.check(), state2.check());
    // Ok(()), Err("whoops, got 1 != 0")
}

但不清楚这比命令式解决方案有什么优势,后者要清楚得多。

impl State<i32> {
    fn check(&self) -> Result<(), String> {
        for x in &self.db {
            check(*x)?;
        }
        Ok(())
    }
}

相关问题