有没有办法在没有宏的情况下简化将选项转换为结果?

fgh*_*ghj 14 rust

我有类似的东西(真正的功能Ini::Section::get来自rusti ini):

impl Foo {
    pub fn get<K>(&'a mut self, key: &K) -> Option<&'a str>
    where
        K: Hash + Eq,
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我必须多次打电话:

fn new() -> Result<Boo, String> {
    let item1 = match section.get("item1") {
        None => return Result::Err("no item1".to_string()),
        Some(v) => v,
    };
    let item2 = match section.get("item2") {
        None => return Result::Err("no item2".to_string()),
        Some(v) => v,
    };
}
Run Code Online (Sandbox Code Playgroud)

要删除代码膨胀,我可以像这样写一个宏:

macro_rules! try_ini_get {
    ($e:expr) => {
        match $e {
            Some(s) => s,
            None => return Result::Err("no ini item".to_string()),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在没有这个宏实现的情况下删除代码重复?

orl*_*rlp 43

如果您使用板条箱,anyhow您可以导入在s 上anyhow::Context添加方法的特征,以将它们转换为s:.contextOptionanyhow::Result

use anyhow::{Result, Context};

fn new() -> Result<Boo> {
    let item1 = section.get("item1").context("no item1")?;
    let item2 = section.get("item2").context("no item2")?;
    // whatever processing...
    Ok(final_result)
}
Run Code Online (Sandbox Code Playgroud)

  • 一个简单的无依赖解决方案永远是最佳实践恕我直言,接受的答案是好的。 (2认同)

pyo*_*yon 26

ok_orok_or_else方法转换Options到Results,并且?运营商与自动化相关的早期样板Err回报.

你可以这样做:

fn new() -> Result<Boo, String> {
    let item1 = section.get("item1").ok_or("no item1")?;
    let item2 = section.get("item2").ok_or("no item2")?;
    // whatever processing...
    Ok(final_result)
}
Run Code Online (Sandbox Code Playgroud)

  • `ok_or` 和 `ok_or_else` 之间的区别:“传递给 `ok_or` 的参数是急切求值的;如果要传递函数调用的结果,建议使用 `ok_or_else`,它是延迟求值的。” (5认同)