一种解决方案是返回Option
转换为Result
,然后用像Result::or_else
方法链的进一步工作和宏像try!
返回早期:或者
struct Thing;
impl Thing {
fn split(&self, size: u8) -> bool { false }
}
fn find_free_block(size: u8) -> Option<*mut Thing> { None }
fn request_mem(size: u8) -> Result<*mut Thing, i32> { Err(1) }
fn the_answer(size: u8) -> Result<bool, i32> {
let thing_ptr = try!(find_free_block(size).ok_or(0).or_else(|_| request_mem(size)));
let thing = unsafe { &*thing_ptr };
Ok(thing.split(size))
}
fn main() {}
:
fn the_answer(size: u8) -> Result<bool, i32> {
find_free_block(size)
.ok_or(0)
.or_else(|_| request_mem(size))
.map(|t| unsafe { &*t })
.map(|t| t.split(size))
}
如果像这样的东西可以工作,会是什么非常好的
fn the_answer(size: u8) -> Result<bool, i32> {
find_free_block(size)
.ok_or_maybe(|| request_mem(size))
.map(|t| unsafe { &*t })
.map(|t| t.split(size))
}
你可以做到这一点现在虽然:
trait Secret<T> {
fn ok_or_maybe<E, F>(self, F) -> Result<T, E>
where F: FnOnce() -> Result<T, E>;
}
impl<T> Secret<T> for Option<T> {
fn ok_or_maybe<E, F>(self, f: F) -> Result<T, E>
where F: FnOnce() -> Result<T, E>
{
match self {
Some(e) => Ok(e),
None => f(),
}
}
}
我们真的很喜欢[MCVE(http://stackoverflow.com/help/mcve),因为它确保了答案适当的,而不是疯狂的猜测。具体来说,我不清楚'util :: request_mem'的签名是什么。从你的评论看来,它似乎会返回某种'Option',但我不太确定。此外,尽管知道您希望避免“解包”,但您并不指定如果request_mem返回“无”会发生什么情况。 –
另外,如果你用*“双缩进匹配语句”编写代码*,那将是一种展示你想要它做什么的方法。 – Shepmaster