Rust接收嵌套借用的构造trait使用时无法推导生命周期如何解决
Rust 嵌套借用构造实例生命周期问题解决方案
错误原因
你遇到的生命周期冲突核心逻辑如下:
- 原函数签名
fn create_bin_with_rubbish<'a,'b, T>()中的'a、'b是由函数调用方指定的生命周期,作用域默认长于当前函数内部的作用域 - 函数内部创建的
matter(切片引用)、rubbish(Paper实例)都是局部变量,生命周期仅存在于函数执行阶段,远短于调用方指定的'a、'b,无法满足泛型约束的生命周期要求
解决方案
使用**高阶trait约束(HRTB,Higher-Ranked Trait Bound)**调整函数的泛型约束,把生命周期参数的声明从函数泛型列表移到trait约束的for<>语法中:
trait GarbageBin<'a,'b>{ fn new(rubbish: &'b Paper<'a>) -> Self; } struct PaperBin<'a,'b> { rubbish: &'b Paper<'a> } struct Paper<'a> { matter: &'a [u8] } impl<'a,'b> GarbageBin<'a,'b> for PaperBin<'a,'b> { fn new(rubbish: &'b Paper<'a>) -> Self{ Self { rubbish } } } // 调整这里的泛型约束,用for<'a,'b>表示T支持任意生命周期的GarbageBin实现 fn create_bin_with_rubbish<T>() where T: for<'a,'b> GarbageBin<'a,'b> { let matter = &[1][..]; let rubbish = Paper{matter}; // 现在可以正常创建实例 let garbage_bin = T::new(&rubbish); // 注意:garbage_bin持有局部变量引用,仅能在当前函数内部使用,不能作为返回值返回 } #[test] fn run() { create_bin_with_rubbish::<PaperBin>(); }
for<'a,'b> GarbageBin<'a,'b>的语义是:泛型类型T实现了所有任意生命周期参数的GarbageBin trait,不管生命周期多短都可以适配,刚好匹配函数内部局部变量的临时生命周期。
扩展说明
如果你后续需要将构造好的GarbageBin实例返回出函数使用,就不能在函数内部创建matter和rubbish,需要将这两个值作为参数从函数外部传入,由调用方来管理它们的生命周期,避免返回悬垂引用。
内容的提问来源于stack exchange,提问作者Robert Kalinke
相关产品推荐
相关产品推荐

