将来称为“自己”

时间:2019-07-10 16:57:10

标签: rust future

以下(人为)示例具有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())),
        )
    }
}

0 个答案:

没有答案