为何Rust中Arc<dyn Fn(&'b Box<dyn DecodedPacket<'a>>>要求'a满足'static约束
报错原因说明
- 第一个核心原因是trait对象的默认生命周期省略规则:Rust中未显式标注生命周期的trait对象会默认被添加
'static约束。你代码中的Arc<dyn Fn(...)>默认等价于Arc<dyn Fn(...) + 'static>,这就是你没显式声明却出现'static要求的来源。 - 第二个问题是生命周期参数的作用域错误:你将
'a、'b声明为receive函数的泛型生命周期参数,意味着这两个生命周期的长度由调用方在调用时指定,必然长于receive函数的内部作用域。但你在函数内部创建的slice是指向栈上临时数组的引用,生命周期仅存在于函数内部,远短于调用方指定的'a,不可能满足DecodedPacket<'a>的生命周期要求。
修复方案
你需要使用高阶生命周期绑定(HRTB) 声明on_packet可以接受任意生命周期的DecodedPacket实例,而非调用方提前指定的固定生命周期,同时避免默认'static约束的问题,修复后的代码如下:
use std::sync::Arc; trait DecodedPacket<'a> {} struct ReferencePacket<'a> { data: &'a [u8], } impl<'a> DecodedPacket<'a> for ReferencePacket<'a> {} struct Decoder {} impl Decoder { // for<'a, 'b> 表示该Fn支持任意的'a、'b生命周期 pub fn receive(&self, on_packet: Arc<dyn for<'a, 'b> Fn(&'b Box<dyn DecodedPacket<'a>>)>) { let slice: &[u8] = &[0, 1, 2]; // 用生命周期省略标记让编译器自动推导内部生命周期 let reference_packet: Box<dyn DecodedPacket<'_>> = Box::new(ReferencePacket { data: slice }); on_packet(&reference_packet); } }
内容的提问来源于stack exchange,提问作者Poperton
相关产品推荐
相关产品推荐

