以下(人为)示例具有chain
方法,该方法调用create_future
方法,该方法将重新调整Future
。将来成功完成后,将返回do_something
方法的结果。
use futures::Future; //0.1.28
type AnError = Box<std::error::Error>;
pub trait Test {
fn do_something(&self) -> Result<(), AnError>;
fn create_future(&self) -> Box<Future<Item = (), Error = AnError>>;
fn chain(&self) -> Box<Future<Item = (), Error = AnError>> {
Box::new(
self.create_future()
.then(|f| f.and_then(|_| self.do_something())),
)
}
}
无法编译:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:11:23
|
11 | .then(|f| f.and_then(|_| self.do_something())),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
--> src/lib.rs:8:5
|
8 | / fn chain(&self) -> Box<Future<Item = (), Error = AnError>> {
9 | | Box::new(
10 | | self.create_future()
11 | | .then(|f| f.and_then(|_| self.do_something())),
12 | | )
13 | | }
| |_____^
= note: ...so that the types are compatible:
expected &&Self
found &&Self
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn futures::future::Future<Error = std::boxed::Box<(dyn std::error::Error + 'static)>, Item = ()> + 'static)>
found std::boxed::Box<dyn futures::future::Future<Error = std::boxed::Box<dyn std::error::Error>, Item = ()>>
问题是在self
调用中使用了self.do_something()
(用Ok(())
替换了此调用,此示例将编译)。
编译器抱怨说,该结构实例(self
)在那个将来可能会过时...似乎很难吞咽,因为已经调用了chain
。
我该如何进行这项工作,并让struct实例在将来进行调用?我正在使用Rust 1.36。
除非我错过了某些事情,否则the suggested solution in the duplicate(作为将来的结果传递参考)是不够的
use futures::Future; //0.1.28
type AnError = Box<std::error::Error>;
pub trait Test {
fn do_something(&self) -> Result<(), AnError>;
fn create_future(&self) -> Box<Future<Item = &Test, Error = AnError>>; //<== CHANGE `Item=()` to `Item=&Test` to return a ref
fn chain(&self) -> Box<Future<Item = (), Error = AnError>> {
Box::new(
self.create_future()
.then(|f| f.and_then(|t| t.do_something())), // <== CHANGE recovering `t` from the future the ref to `Test`, and calling on it
)
}
}
失败
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/lib.rs:10:18
|
10 | self.create_future()
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
--> src/lib.rs:8:5
|
8 | / fn chain(&self) -> Box<Future<Item = (), Error = AnError>> {
9 | | Box::new(
10 | | self.create_future()
11 | | .then(|f| f.and_then(|t| t.do_something())), // <== change there
12 | | )
13 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:10:13
|
10 | self.create_future()
| ^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn futures::future::Future<Error = std::boxed::Box<(dyn std::error::Error + 'static)>, Item = ()> + 'static)>
found std::boxed::Box<dyn futures::future::Future<Error = std::boxed::Box<dyn std::error::Error>, Item = ()>>
解决方案:
为self
和Future分配明确的生存期。
从@Shepmaster(感谢)游乐场复制。
type AnError = Box<std::error::Error>;
pub trait Test {
fn do_something(&self) -> Result<(), AnError>;
fn create_future(&self) -> Box<Future<Item = &Test, Error = AnError>>;
fn chain<'a>(&'a self) -> Box<Future<Item = (), Error = AnError> + 'a> {
Box::new(
self.create_future()
.then(|f| f.and_then(|_| self.do_something())),
)
}
}