Rust 无法推断包含闭包引用的结构的生存期

Rust 无法推断包含闭包引用的结构的生存期,rust,lifetime,Rust,Lifetime,我正在尝试编译我的代码的这个简化且自包含的版本: struct FragMsgReceiver<'a, 'b: 'a> { recv_dgram: &'a mut FnMut(&mut [u8]) -> Result<&'b mut [u8], ()>, } impl<'a, 'b> FragMsgReceiver<'a, 'b> { fn new( recv_dgram: &

我正在尝试编译我的代码的这个简化且自包含的版本:

struct FragMsgReceiver<'a, 'b: 'a> {
    recv_dgram: &'a mut FnMut(&mut [u8]) -> Result<&'b mut [u8], ()>,
}

impl<'a, 'b> FragMsgReceiver<'a, 'b> {
    fn new(
        recv_dgram: &'a mut FnMut(&mut [u8])
            -> Result<&'b mut [u8], ()>
    ) -> Self {
        FragMsgReceiver { recv_dgram }
    }
}

fn main() {
    let recv_dgram = |buff: &mut [u8]| Ok(buff);
    let fmr = FragMsgReceiver::new(&mut recv_dgram);
}
从错误消息中我了解到,编译器不理解
buff
引用(recv_dgram的参数)实际上可以比
recv_dgram
的内部体活得更长。不过我可能错了


为了提供一些上下文,我试图创建一个包装Rust Tokio UDP套接字的结构。为此,我引用一个函数
recv\dgram
。在我的原始代码中,此函数以缓冲区作为参数,并返回一个
Future
。当
未来
准备就绪时,缓冲区将被填满。
Future
的项还包含发送方地址和写入缓冲区的字节数。

让我们从恢复声明中的省略生存期开始

struct FragMsgReceiver<'a, 'b: 'a> {
    recv_dgram: &'a mut for<'c> FnMut(&'c mut [u8]) -> Result<&'b mut [u8], ()>,
}
在这里,生命周期省略做了正确的事情,但编译器仍然抱怨:“预期的绑定生命周期参数,找到了具体的生命周期”,指向
FragMsgReceiver::new(&mut recv_dgram)

此错误是由Rust的类型推断限制引起的。我们需要通过强制闭包的类型来辅助推理

fn约束\u处理程序(f:f)->f
哪里
F:FnMut(&mut[u8])->结果,
{
F
}
// ...
让mut recv_dgram=constraint_handler(| buff | Ok(buff));


为了澄清,
for&u32
的类型
for&a u32

不是一个函数;结束了。是否有理由需要引用trait对象而不仅仅使用泛型?请在闭包参数上删除类型说明符以允许推理工作,然后指定传递给闭包的值与结果具有相同的生存期,然后修复
mut
限定符@谢普马斯特:谢谢!还有一件事我无法解决:我想让“a”比“b”活得长,因为RecvdGram有各种各样的缓冲区,我认为它们的寿命不应该与“a”有关。当我试图删除'b:'a时,我得到一个编译错误<代码>在类型`&'a mut std::ops::FnMut(&'b mut[u8])->&'b mut[u8]+'a中,引用的生存期比它引用的数据更长。如何解决这个问题?@Shepmaster:我很欣赏你通过编辑和标记副本所做的工作,但是我不认为这个问题是上述问题的重复。在我把问题贴在这里之前,我读了这两篇文章。red75prime的回答中有一些我在别处找不到的关于生命的信息。谢谢你的客气话。然而,我不只是将问题标记为重复问题,每当我们获得新知识时,我都会用新知识更新重复问题。如果您现在检查它们,它们都已增强。这避免了未来用户必须导航到N个不同的问题才能获得所有不同的答案。因此,我认为它们仍然是复制品;但欢迎你投票重新开放。雷德75首相和谢普马斯特,你救了我一天!
type FnTraitObject = FnMut(&mut [u8]) -> Result<&mut [u8], ()>;

struct FragMsgReceiver<'a> {
    recv_dgram: &'a mut FnTraitObject,
}

impl<'a> FragMsgReceiver<'a> {
    fn new(recv_dgram: &'a mut FnTraitObject) -> Self {
        FragMsgReceiver { recv_dgram }
    }
}
fn constrain_handler<F>(f: F) -> F
where
    F: FnMut(&mut [u8]) -> Result<&mut [u8], ()>,
{
    f
}

// ...

let mut recv_dgram = constrain_handler(|buff| Ok(buff));