【发布时间】:2020-04-20 05:07:08
【问题描述】:
我有一个带有Result 类型参数的方法。我非常喜欢链接,所以我在参数上使用and_then。在某些时候,我想有条件地从and_then 内部返回整个方法(因此有机会可以调用另一个and_then 方法):
enum Good {
Ok,
Good,
VeryGood,
}
enum Pizza {
Tomato,
Pineapple,
}
enum Burger {
Cow,
}
enum Food {
Pizza(Pizza),
Burger(Burger),
}
fn main() {}
fn s(r: Result<Good, ()>) -> Result<Food, ()> {
r.and_then(|o| {
match o {
// Should be called in the next and_then block
Good::Ok => Ok(Pizza::Tomato),
// Should be called in the next and_then block
Good::Good => Ok(Pizza::Pineapple),
Good::VeryGood => {
// I am done. Don't call the next and_then block, but rather return the whole value to the caller.
return Ok(Food::Burger(Burger::Cow));
}
}
})
.and_then(|p: Pizza| {
// At this point, the closure input value should be pizza, because that's the only returned value
Ok(Food::Pizza(p))
})
}
我得到各种编译器错误:
error[E0308]: mismatched types
--> src/main.rs:30:27
|
30 | return Ok(Food::Burger(Burger::Cow));
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Pizza`, found enum `Food`
|
= note: expected type `Pizza`
found type `Food`
我希望有办法让它编译。我可以分解该方法并摆脱and_then,但也许有and_then 的方法。
在我的真实代码中,我有更多 and_then 将类型映射到其他类型、错误映射等,所以这是我面临的问题的简化再现路径。
这是我的代码库中复制粘贴的代码,显示了多个 and_then。我将来自外部库的错误映射到我自己的错误类型中,因此如果有错误可以自动返回。我想继续更改从and_then 获得的类型,这样我最终可以获得User 类型(尽管它目前不起作用)。一种选择是不链接块并创建单独的值,但我希望我可以直接将值返回给闭包内的调用者。
db_session
.query_with_values(query, values)
.map_err(|e| {
error!("{:?}", e);
TechnicalServerError::SERVER_RETRY
})
.and_then(|f| {
f.get_body().map_err(|e| {
error!("{:?}", e);
TechnicalServerError::SERVER_RETRY
})
})
.and_then(|b| b.into_rows().ok_or(TechnicalServerError::SERVER_RETRY))
.and_then(|mut c| {
if let Some(row) = c.pop() {
User::try_from_row(row).map_err(|e| {
error!("{:?}", e);
TechnicalServerError::SERVER_INVALID
})
} else {
return Ok(Login::Other(LoginResult::UNKNOWN_USER));
}
})
.and_then(|u| {
// 'u' should be of type 'user' at this point
// some user code here...
})
【问题讨论】:
-
您发布的代码未编译。您能否对其进行编辑以更好地向我们展示工作流程?还有,你怎么这么早回来?有具体原因吗?对我来说,使用带有单个返回点的
map会更好地服务此代码。 -
@DanielFath 查看我的编辑
-
看来Is there any way to return from a function from inside a closure? 的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
您还应该阅读How do you define custom
Errortypes in Rust?,其中讨论了如何使?自动包装底层错误。
标签: rust