我有一个函数可以通过以下方式执行字符串替换regex::Regex::replace
通过一个闭包执行一些操作Captures
:
pub fn solve_dice_expression(expression: String) -> Result<i64, Box<dyn Error>> {
lazy_static! {
static ref PATTERN: Regex = Regex::new(r"(\d+)d(\d+)").expect("Problem compiling regex");
}
// For every match on the Dice expression regex, roll it in-place.
let rolled_expression = PATTERN.replace(&expression, |caps: &Captures| {
let diceroll_str = &caps.get(0).unwrap().as_str().to_string();
let dice = Dice::from_string(&diceroll_str).unwrap();
return format!("{}", roll_dice(&mut rng, &dice));
});
// Calculate the result
let result = eval(&rolled_expression)?.as_int()?;
return Ok(result);
}
我尝试通过返回来让错误冒出来Result<..., Box<dyn Error>>
,主要通过?
。然而,在关闭传递给regex::Regex::replace
,我不确定如何传播可能发生的任何可能的错误,因为它期望闭包返回String
而不是一个Result
.
处理该闭包中发生的错误的正确方法是什么?
你不能轻易。
你能做的就是将错误隐藏在一个可变的变量中Option
,然后检查替换完成后:
use regex::{Captures, Regex}; // 1.3.3
use std::borrow::Cow;
type Error = Box<dyn std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;
fn example<'s>(r: &Regex, s: &'s str) -> Result<Cow<'s, str>> {
let mut error = None;
let v = r.replace(s, |caps: &Captures| {
// TODO: Optimize by checking if we had an error already and exit early
let digits = caps.get(0).unwrap().as_str();
// Uncomment to see the failure
// let digits = "bad";
match digits.parse::<i32>() {
Ok(v) => Cow::Owned((v + 1).to_string()),
Err(e) => {
// Save the error somewhere
error = Some(e);
// We are going to discard the replacement,
// so it doesn't matter what we return
Cow::Borrowed("")
}
}
});
match error {
Some(e) => Err(Box::new(e)),
None => Ok(v),
}
}
fn main() {
let r = Regex::new(r"\d+").unwrap();
let v = example(&r, "1");
println!("{:?}", v);
}
您还可以潜在地实施Replacer您自己的类型的特征可以简化这一点,并可能稍微优化它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)