有没有一种方法可以在没有宏的情况下简化将选项转换为结果的过程?

我有这样的东西(真正的函数是 锈印中的 Ini::Section::get) :

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

我得打好几次电话:

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,
};
}

为了消除代码膨胀,我可以编写如下宏:

macro_rules! try_ini_get {
($e:expr) => {
match $e {
Some(s) => Ok(s),
None => Err("no ini item".to_string()),
}
}
}

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

44357 次浏览

ok_orok_or_else方法将 Option转换为 Result,而 ?操作员将自动执行与早期 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)
}

如果你使用的是 anyhow,你可以导入 anyhow::Context特性,这样就可以在 Option上增加 .context方法,把它们变成 anyhow::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)
}