我有一个函数可以返回具有User
特征的未来。我有它的两个具体实现:AnonymousUser
和BaseUser
. 要获得BaseUser
,在身份验证之后,我必须去数据库并获取它,这可能成功也可能不成功,并以正确的类型返回新的未来。我尝试了以下(操场):
extern crate futures; // 0.1.23
extern crate rand; // 0.5.4
use futures::future::{ok, Future};
use std::io::Error;
trait User {}
#[derive(Debug)]
struct AnonymousUser;
impl User for AnonymousUser {}
#[derive(Debug)]
struct BaseUser;
impl User for BaseUser {}
fn fetch_base_user() -> impl Future<Item = BaseUser, Error = Error> {
ok(BaseUser)
}
fn run_future() -> impl Future<Item = impl User, Error = Error> {
match rand::random::<bool>() {
true => fetch_base_user().from_err().then(move |res| match res {
Ok(user) => ok(user),
Err(_) => ok(AnonymousUser),
}),
false => ok(AnonymousUser),
}
}
fn main() {
run_future().and_then(move |user| println!("User {:?}", user));
}
这失败了,因为then
函数的返回需要一个BaseUser
:
error[E0308]: match arms have incompatible types
--> src/main.rs:23:62
|
23 | true => fetch_base_user().from_err().then(move |res| match res {
| ______________________________________________________________^
24 | | Ok(user) => ok(user),
25 | | Err(_) => ok(AnonymousUser),
| | ----------------- match arm with an incompatible type
26 | | }),
| |_________^ expected struct `BaseUser`, found struct `AnonymousUser`
|
= note: expected type `futures::FutureResult<BaseUser, _>`
found type `futures::FutureResult<AnonymousUser, _>`
我尝试强制返回类型:
use futures::future::FutureResult;
fn run_future() -> impl Future<Item=impl User, Error=Error> {
match rand::random::<bool>() {
true => fetch_base_user().from_err().then(move |res| ->
FutureResult<impl User, Error> { // Forcing the result type here
match res {
Ok(user) => ok(user),
Err(_) => ok(AnonymousUser),
}
}),
false => ok(AnonymousUser),
}
}
失败了:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> src/main.rs:27:22
|
27 | FutureResult<impl User, Error> { // Forcing the result type here
| ^^^^^^^^^
我尝试使用Box
es 返工返工,这几乎奏效了(操场)
fn run_future() -> impl Future<Item = Box<impl User>, Error = Error> {
match rand::random::<bool>() {
true => fetch_base_user()
.from_err()
.then(move |res| -> FutureResult<Box<User>, Error> {
match res {
Ok(user) => ok(Box::new(user) as Box<User>),
Err(_) => ok(Box::new(AnonymousUser) as Box<User>),
}
}),
false => ok(Box::new(AnonymousUser) as Box<User>),
}
}
失败了
error[E0308]: match arms have incompatible types
--> src/main.rs:22:5
|
22 | / match rand::random::<bool>() {
23 | | true => fetch_base_user().from_err().then(move |res| match res {
24 | | Ok(user) => ok(Box::new(user) as Box<User>),
25 | | Err(_) => ok(Box::new(AnonymousUser) as Box<User>),
26 | | }),
27 | | false => ok(Box::new(AnonymousUser) as Box<User>),
| | ---------------------------------------- match arm with an incompatible type
28 | | }
| |_____^ expected struct `futures::Then`, found struct `futures::FutureResult`
|
= note: expected type `futures::Then<futures::future::FromErr<impl futures::Future, _>, futures::FutureResult<std::boxed::Box<User>, _>, [closure@src/main.rs:23:51: 26:10]>`
found type `futures::FutureResult<std::boxed::Box<User>, _>`
所以我想这只是迫使两者成为相同的结果类型的问题