我如何从高阶特征绑定特征返回关联类型?

问题描述 投票:5回答:2

我具有一个特征,该特征具有反序列化关联类型的功能。但是,该关联的类型必须具有调用者确定的生存期,因此我有一个单独的特征,我使用了绑定到更高的特征,以便可以在任何生命周期中反序列化。

我需要使用返回此关联类型的闭包。

我有以下代码可以做到这一点:

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::OutMyEndpointBody,我从闭包中返回它,但是Rust认为它们不是同一类型。我猜是因为Rust为MyEndpointBody类型选择了不兼容的匿名生存期,但我不知道该如何解决。

如何使此代码起作用,以便可以将闭包与HRTB相关的类型一起使用?

我具有一个特征,该特征具有反序列化关联类型的功能。但是,该关联的类型必须具有调用者决定的生存期,因此我有一个单独的特征,我使用一个更高的...... >>

rust traits higher-rank-types
2个回答
0
投票

您能否检查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" });
}

0
投票

DeserializeBody定义为:

© www.soinside.com 2019 - 2024. All rights reserved.