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));