Rust 多个struct字段如何可以是使用相同的更高类型生存期的泛型?

Rust 多个struct字段如何可以是使用相同的更高类型生存期的泛型?,rust,lifetime,Rust,Lifetime,My structReadingState将函数recv_dgram作为其new()方法中的参数recv_dgram将具有某个生存期的缓冲区作为参数,并返回特定类型的未来。此future的项包含作为参数提供的缓冲区,其生存期与'r相同 这就是ReadingState的样子: struct FragMsgReceiver<'a, A, FUNC: 'a> where FUNC: for<'r> FnMut(&'r [u8]) -> Fu

My struct
ReadingState
将函数
recv_dgram
作为其
new()
方法中的参数
recv_dgram
将具有某个生存期的缓冲区作为参数,并返回特定类型的未来。此future的
包含作为参数提供的缓冲区,其生存期与
'r
相同

这就是
ReadingState
的样子:

struct FragMsgReceiver<'a, A, FUNC: 'a>
where
    FUNC: for<'r> FnMut(&'r [u8])
        -> Future<Item = (&'r [u8], usize, A), Error = io::Error>,
{
    frag_state_machine: FragStateMachine,
    recv_dgram: &'a mut FUNC,
    get_cur_instant: &'a mut FnMut() -> Instant,
}

struct ReadingState<'a, 'c, A, FUNC: 'a, F>
where
    F: Future<Item = (&'c mut [u8], usize, A), Error = io::Error>,
    FUNC: for<'r> FnMut(&'r [u8])
        -> Future<Item = (&'r [u8], usize, A), Error = io::Error>,
{
    frag_msg_receiver: FragMsgReceiver<'a, A, FUNC>,
    temp_buff: Vec<u8>,
    res_buff: &'c mut [u8],
    opt_read_future: Option<F>,
}
理想解决方案(这不是有效的防锈代码)的形式如下:

struct ReadingState<'a, 'c, A, FUNC: 'a, F> 
    where for <'r> {
        F: Future<Item = (&'r mut [u8], usize, A), Error = io::Error>,
        FUNC: FnMut(&'r [u8]) -> F,
    }
{
    // ...
}
struct ReadingState{
F:未来的F,
}
{
// ...
}
我不知道如何用现有的语法实现这一点

编辑:我制作了尽可能小的自包含示例,但由于可能不同的原因,它没有编译。我把它包括在这里():

trait MockFutureTrait{
类型项目;
fn get_item(self)->self::item;
}
类型FnTraitObject=FnMut(&mut[u8])->mockfuturetracit;
结构模拟未来{
项目:T,
}
impl MockFutureTrait for MockFuture{
类型项=T;
fn获取项目(self)->self::项目{
自选项目
}
}
结构FragMsgReceiver,
res_buff:&'c mut[u8],
阅读未来:F,
}
fn main(){
让mut recv_dgram=| buf:&mut[u8]|{
模拟未来{
项目:buf,
}
};
设fmr=FragMsgReceiver{
记录:多个记录(&M),
};
}
我得到的编译错误是:

error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:33:26: 37:6] as std::ops::FnOnce<(&'r mut [u8],)>>::Output == MockFutureTrait<Item=&'r mut [u8]> + 'static`
  --> src/main.rs:40:21
   |
40 |         recv_dgram: &mut recv_dgram,
   |                     ^^^^^^^^^^^^^^^ expected struct `MockFuture`, found trait MockFutureTrait
   |
   = note: expected type `MockFuture<&mut [u8]>`
              found type `MockFutureTrait<Item=&mut [u8]> + 'static`
   = note: required for the cast to the object type `for<'r> std::ops::FnMut(&'r mut [u8]) -> MockFutureTrait<Item=&'r mut [u8]> + 'static + 'static`

error: aborting due to previous error

error: Could not compile `noncompiling_lifetime_trait`.
error[E0271]:类型不匹配解析`for>::Output==mockfuturetracit src/main.rs:40:21
|
40 |记录:和多个记录,
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^预期结构为“MockFuture”,但找到了trait mockfutur
|
=注意:预期类型为'MockFuture`
找到类型“MockFutureTracit+”静态`

=注意:对于对象类型`for MockFutureTracit的强制转换是必需的,从Rust 1.20开始,您希望执行的操作是不可能的。您需要在类型参数
F
上绑定正确的生存期。解决方案如下所示(显然,我无法测试它,因为尚未实现泛型关联类型):

使用std::marker::PhantomData;
特征FragFutureFamily{
F型;
}
结构FragMsgReceiver
哪里
FF:FragFutureFamily,
FUNC:for FF::F
哪里
F:未来FnMut(&'r[u8])->FF::F,
临时buff:Vec,
res_buff:&'c mut[u8],
opt_read_future:选项,
_幻影未来家族:幻影数据,
}

注意:我将
F
type参数保留在
ReadingState
上,因为该类型与
FragFutureFamily::F
稍有不同,但如果您能使类型一致,您可以将
opt\u read\u future
的类型更改为
option是否希望
FUNC
的返回值与
F
相同?不幸的是,我不确定我是否能理解这个问题。你能不能把它简化为一个例子,最好是可以运行的?注意:
选项
上的
mem::replace
可以使用@Timidger:I不知道
take
重新创建。这真的很酷,谢谢。我不知道幻影数据。我假设它用于为类型添加约束,非常有趣。我希望我不需要使用框解决方法,因为我想避免分配):我添加了自包含的代码示例,但它不可编译。您不能让函数返回
mockfuturetracit
,因为这是一个未大小化的类型。您需要返回一个实现
mockfuturetracit
的具体类型,但不能指定一个适用于每个生命周期的具体类型。我尝试使用Boxed idea的内容可以在
error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:33:26: 37:6] as std::ops::FnOnce<(&'r mut [u8],)>>::Output == MockFutureTrait<Item=&'r mut [u8]> + 'static`
  --> src/main.rs:40:21
   |
40 |         recv_dgram: &mut recv_dgram,
   |                     ^^^^^^^^^^^^^^^ expected struct `MockFuture`, found trait MockFutureTrait
   |
   = note: expected type `MockFuture<&mut [u8]>`
              found type `MockFutureTrait<Item=&mut [u8]> + 'static`
   = note: required for the cast to the object type `for<'r> std::ops::FnMut(&'r mut [u8]) -> MockFutureTrait<Item=&'r mut [u8]> + 'static + 'static`

error: aborting due to previous error

error: Could not compile `noncompiling_lifetime_trait`.
use std::marker::PhantomData;

trait FragFutureFamily<A> {
    type F<'a>: Future<Item = (&'a [u8], usize, A), Error = io::Error>;
}

struct FragMsgReceiver<'a, A, FUNC: 'a, FF>
where
    FF: FragFutureFamily<A>,
    FUNC: for<'r> FnMut(&'r [u8]) -> FF::F<'r>,
{
    frag_state_machine: FragStateMachine,
    recv_dgram: &'a mut FUNC,
    get_cur_instant: &'a mut FnMut() -> Instant,
    _phantom_future_family: PhantomData<FF>,
}

struct ReadingState<'a, 'c, A, FUNC: 'a, F, FF>
where
    F: Future<Item = (&'c mut [u8], usize, A), Error = io::Error>,
    FF: FragFutureFamily<A>,
    FUNC: for<'r> FnMut(&'r [u8]) -> FF::F<'r>,
{
    frag_msg_receiver: FragMsgReceiver<'a, A, FUNC, FF>,
    temp_buff: Vec<u8>,
    res_buff: &'c mut [u8],
    opt_read_future: Option<F>,
    _phantom_future_family: PhantomData<FF>,
}