futures
を使用して非同期操作を試していましたが、tokio
クレートは問題ありませんでした。今私は非同期にデータをロードし、次にいくつかの変換を実行するストレージを実装していますが、私のインターフェイスには理解できない生涯の問題があるようです。動作時にライフタイムコンパイラエラーが発生しました。<Future>
これは、同じ症状を示している縮小されたテストコードです。実際の関数本体は常に返すエラーよりも、より合理的なアクションを実行します。私はhyper
またはtokio-postgres
は一見持っていたと書かれている
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>, [[email protected]/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)
| ^^^^^^^^^^^^^^^^
前のコード:
extern crate futures;
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)
}
}
コンパイラは、次の寿命の問題で、このサンプルコードを拒否します同じロジックですが、このようなエラーは発生しませんでした。私はどこで生涯が参照なしでここで間違っていたか見ることさえできません。私の腸の感覚は、何となく一般的なObj
パラメータに関係していると言います。静的寿命の制限は正しく感じません。
コンパイルエラーの原因は何ですか?
あなたはそうです、私は多少の生涯を見過ごしました。私もこのアイデアを持っていましたが、私の元の文脈ははるかに複雑で、おそらくまだいくつかのエラーが残っています。私は問題のあることは、コンパイラのメッセージでは何もこのエラーの原因として自己を参照していないと思うので、問題がどこにあるかを推測することしかできません。 それを指摘してくれてありがとう! –
「ボックス化できません」私はtokioについては何も知りませんが、 'Box <'a + Future <...>>'仕事はできませんか? – trentcl
あなたはおそらく正しいですが、生涯制限された未来はあまり役に立たないでしょう。もう一度見ようとします。 – Stefan