首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回Box<Future>操作时的生存期编译器错误

返回Box<Future>操作时的生存期编译器错误
EN

Stack Overflow用户
提问于 2017-10-24 18:21:37
回答 1查看 610关注 0票数 4

我正在使用futurestokio机箱进行异步操作的实验,没有问题。现在,我正在实现一个存储,它异步加载数据,然后执行一些转换,但我的接口似乎存在一些无法理解的终身问题。

这是一个显示相同症状的简化测试代码;真正的功能体执行比总是返回错误更合理的操作:

代码语言:javascript
复制
extern crate futures; // v0.1 (old)

use futures::prelude::*;
use futures::future;

pub enum MyError {
    SomeError,
}

pub trait KeyValueStore {
    type ValueType;

    fn load(&self, key: String) -> Box<Future<Item = Vec<u8>, Error = MyError>>;
    fn deserialize(&self, serialized_obj: Vec<u8>) -> Result<Self::ValueType, MyError>;

    fn resolve(&self, key: String) -> Box<Future<Item = Self::ValueType, Error = MyError>>;
}

pub struct Storage<Obj> {
    _unused: std::marker::PhantomData<Obj>,
}

impl<Obj: 'static> KeyValueStore for Storage<Obj> {
    type ValueType = Obj;

    fn deserialize(&self, serialized_obj: Vec<u8>) -> Result<Self::ValueType, MyError> {
        Err(MyError::SomeError)
    }

    fn load(&self, key: String) -> Box<Future<Item = Vec<u8>, Error = MyError>> {
        Box::new(future::err(MyError::SomeError))
    }

    fn resolve(&self, key: String) -> Box<Future<Item = Self::ValueType, Error = MyError>> {
        let result = self.load(key).and_then(|bytes| self.deserialize(bytes));
        Box::new(result)
    }
}

编译器拒绝包含以下生存期问题的示例代码:

代码语言:javascript
复制
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/main.rs:36:9
   |
36 |         Box::new(result)
   |         ^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 34:5...
  --> src/main.rs:34:5
   |
34 | /     fn resolve(&self, key: String) -> Box<Future<Item = Self::ValueType, Error = MyError>> {
35 | |         let result = self.load(key).and_then(|bytes| self.deserialize(bytes));
36 | |         Box::new(result)
37 | |     }
   | |_____^
note: ...so that the type `futures::AndThen<std::boxed::Box<futures::Future<Error=MyError, Item=std::vec::Vec<u8>>>, std::result::Result<Obj, MyError>, [closure@src/main.rs:35:46: 35:77 self:&&Storage<Obj>]>` will meet its required lifetime bounds
  --> src/main.rs:36:9
   |
36 |         Box::new(result)
   |         ^^^^^^^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Error=MyError, Item=Obj> + 'static>, found std::boxed::Box<futures::Future<Error=MyError, Item=Obj>>)
  --> src/main.rs:36:9
   |
36 |         Box::new(result)
   |         ^^^^^^^^^^^^^^^^

我以前用hypertokio-postgres编写的代码似乎具有相同的逻辑,但从未产生过这样的错误。如果没有推荐信,我甚至都看不出这里的生活会出什么问题。我的直觉是,它在某种程度上与通用的Obj参数有关,静态生存期限制感觉不正确。

是什么情况导致编译错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-24 19:42:02

self in self.deserialize需要从&self参数到resolve的生存期;不能将结果装箱为Box<Future<..>>,这需要为装箱Future设置'static生存期。

您可以用Box<Future<..> + 'a>覆盖装箱未来的生存期要求(其中'aself参数的生存期;您需要在特征和实现中更改resolve签名);但是对结果没有什么可做的,因为通常的Future-based事件循环需要运行Future'static生存期。

相反,您可以通过使deserialize成为一个“静态方法”来解决这个问题,即删除&self参数并通过Self::deserialize调用它。

当使用特征作为类型时,默认的生存期要求(在本例中为'static)在引用中特征对象中记录。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46917486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档