我正在尝试使用在main()
中创建的结构并将其传递给返回框Future
的函数。但是,我遇到了终生和借用问题,似乎无法彻底解决这个问题。
这是我的结构和功能:
extern crate futures; // 0.1.21
extern crate tokio_core; // 0.1.17
use futures::{future::ok, Future};
pub struct SomeStruct {
some_val: u32,
}
impl SomeStruct {
pub fn do_something(&self, value: u32) -> u32 {
// Do some work
return self.some_val + value;
}
}
fn main() {
let core = tokio_core::reactor::Core::new().unwrap();
let my_struct = SomeStruct { some_val: 10 };
let future = get_future(&my_struct);
core.run(future);
let future2 = get_future(&my_struct);
core.run(future2);
}
fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = u32, Error = ()>> {
let fut = ok(20).and_then(|val| {
let result = some_struct.do_something(val);
ok(result)
});
Box::new(fut)
}
编译时,会发生以下错误:
error[E0621]: explicit lifetime required in the type of `some_struct`
--> src/main.rs:33:5
|
28 | fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = u32, Error = ()>> {
| ----------- consider changing the type of `some_struct` to `&'static SomeStruct`
...
33 | Box::new(fut)
| ^^^^^^^^^^^^^ lifetime `'static` required
我认为发生错误是因为SomeStruct
中使用Future
并且可能在main()
范围之外使用,因此编译器要求我将生命周期更改为{{1 }}。这是我到目前为止尝试过的(不成功):
'static
,这会在'static
中产生借用问题。main()
移动val
,这会在ok(20).and_then(move |val| {
的第二次调用中产生问题。get_future()
为静态(如建议here),但尝试时会遇到宏错误。可以找到整个示例here。我省略了一些细节来创建一个最小的例子。使用SomeStruct
和tokio-core
会出现问题。不幸的是,由于另一个库的依赖性,迁移到版本futures = "0.1"
不是一个选项。
答案 0 :(得分:2)
默认情况下,返回一个盒装特征对象绑定'static
。按照编译器的建议并提供明确的生命周期,但不是'static
:
fn get_future<'a>(some_struct: &'a SomeStruct) -> Box<Future<Item = u32, Error = ()> + 'a> {
let fut = ok(20).and_then(move |val| {
let result = some_struct.do_something(val);
ok(result)
});
Box::new(fut)
}
您还必须使用move
将some_struct
的所有权转移到关闭,并将core
更改为可变。您还应该处理由core.run
产生的潜在错误。
对于提供的示例,您还可以返回impl Future
:
fn get_future<'a>(some_struct: &'a SomeStruct) -> impl Future<Item = u32, Error = ()> +'a {
ok(20).and_then(move |val| {
let result = some_struct.do_something(val);
ok(result)
})
}
另见: