我具有一个特征,该特征具有反序列化关联类型的功能。但是,该关联的类型必须具有调用者确定的生存期,因此我有一个单独的特征,我使用了绑定到更高的特征,以便可以在任何生命周期中反序列化。
我需要使用返回此关联类型的闭包。
我有以下代码可以做到这一点:
trait Endpoint: for<'a> DeserializeBody<'a> {} trait DeserializeBody<'a> { type Out: 'a; fn deserialize(raw_body: &'a [u8]) -> Self::Out; } fn store_ep<EP, F>(func: F) where EP: Endpoint, F: 'static + for<'a> Fn(&'a [u8]) -> <EP as DeserializeBody<'a>>::Out, { let _ = Box::new(func); unimplemented!(); } // ///////////////////////////////////////////////////////// struct MyEndpoint; struct MyEndpointBody<'a> { pub string: &'a str, } impl Endpoint for MyEndpoint {} impl<'a> DeserializeBody<'a> for MyEndpoint { type Out = MyEndpointBody<'a>; fn deserialize(raw_body: &'a [u8]) -> Self::Out { unimplemented!(); } } // ///////////////////////////////////////////////////////// fn main() { store_ep::<MyEndpoint, _>(|raw_body| MyEndpointBody { string: "test" }); }
我认为应该可以,但是当我检查它时,出现类型错误:
error[E0271]: type mismatch resolving `for<'a> <[closure@src/main.rs:33:31: 33:75] as std::ops::FnOnce<(&'a [u8],)>>::Output == <MyEndpoint as DeserializeBody<'a>>::Out` --> src/main.rs:33:5 | 7 | fn store_ep<EP, F>(func: F) | -------- ... 10 | F: 'static + for<'a> Fn(&'a [u8]) -> <EP as DeserializeBody<'a>>::Out, | -------------------------------- required by this bound in `store_ep` ... 33 | store_ep::<MyEndpoint, _>(|raw_body| MyEndpointBody { string: "test" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found struct `MyEndpointBody` | = note: expected associated type `<MyEndpoint as DeserializeBody<'_>>::Out` found struct `MyEndpointBody<'_>` = note: consider constraining the associated type `<MyEndpoint as DeserializeBody<'_>>::Out` to `MyEndpointBody<'_>` or calling a method that returns `<MyEndpoint as DeserializeBody<'_>>::Out` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
这很令人困惑,因为
MyEndpoint::Out
是MyEndpointBody
,我从闭包中返回它,但是Rust认为它们不是同一类型。我猜是因为Rust为MyEndpointBody
类型选择了不兼容的匿名生存期,但我不知道该如何解决。
如何使此代码起作用,以便可以将闭包与HRTB相关的类型一起使用?
我具有一个特征,该特征具有反序列化关联类型的功能。但是,该关联的类型必须具有调用者决定的生存期,因此我有一个单独的特征,我使用一个更高的...... >>
您能否检查that一个
trait Endpoint: for<'a> DeserializeBody<'a> {}
trait DeserializeBody<'a> {
type Out: 'a;
fn deserialize(raw_body: &'a [u8]) -> Self::Out;
}
fn store_ep<'a, EP, F>(func: F)
where
EP: Endpoint,
F: 'static + Fn(&'a [u8]) -> <EP as DeserializeBody<'a>>::Out,
{
let _ = Box::new(func);
unimplemented!();
}
// /////////////////////////////////////////////////////////
struct MyEndpoint;
struct MyEndpointBody<'a> {
pub string: &'a str,
}
impl Endpoint for MyEndpoint {}
impl<'a> DeserializeBody<'a> for MyEndpoint {
type Out = MyEndpointBody<'a>;
fn deserialize(raw_body: &'a [u8]) -> Self::Out {
unimplemented!();
}
}
// /////////////////////////////////////////////////////////
fn main() {
store_ep::<MyEndpoint, _>(|raw_body| MyEndpointBody { string: "test" });
}
将DeserializeBody
定义为: