在盒装未来中使用引用变量时“需要显式生命周期”

flo*_*ck0 3 future lifetime rust borrowing rust-tokio

我正在尝试使用创建的结构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)
}
Run Code Online (Sandbox Code Playgroud)

编译时,出现以下错误:

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)
}
Run Code Online (Sandbox Code Playgroud)

我认为发生错误是因为在 s 范围SomeStruct内使用Future并且可能在main()s 范围之外使用,因此编译器要求我将生命周期更改为'static. 这是我迄今为止尝试过的(不成功):

  • 将生命周期更改'static为编译器建议的值,这会在main().
  • 按照编译器的建议进行val添加ok(20).and_then(move |val| {,这会在第二次调用get_future().
  • 使用lazy_static crate显式初始化SomeStruct为静态(如此处建议的那样),但是在尝试时遇到了宏错误。

整个示例可以在这里找到。我省略了一些细节来创建一个最小的示例。tokio-core使用和会出现问题futures = "0.1""0.2"不幸的是,由于依赖另一个库,迁移到版本不是一个选择。

She*_*ter 5

默认情况下,返回装箱特征对象有一个'static界限。按照编译器的建议进行操作并提供显式的生命周期,但不是'static

fn get_future<'a>(some_struct: &'a SomeStruct) -> Box<dyn Future<Item = u32, Error = ()> + 'a> {
    let fut = future::ok(20).and_then(move |val| {
        let result = some_struct.do_something(val);
        future::ok(result)
    });
    Box::new(fut)
}
Run Code Online (Sandbox Code Playgroud)

您还必须使用move将所有权转移some_struct到闭包并更改core为可变的。您还应该处理由core.run.

对于提供的示例,您还可以返回impl Future

fn get_future<'a>(some_struct: &'a SomeStruct) -> impl Future<Item = u32, Error = ()> +'a {
    future::ok(20).and_then(move |val| {
        let result = some_struct.do_something(val);
        future::ok(result)
    })
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: