使用GAT作为泛型参数的Trait遭遇“值借用生命周期不足”错误求助
解决GAT Trait作为泛型参数时的生命周期问题
你的问题核心在于生命周期绑定的方向错了:act函数里的泛型生命周期'a是由调用者指定的,但你在函数内部创建的Owned实例生命周期只存在于函数执行期间,根本不可能满足'a可能要求的更长生命周期(比如调用者可能期望'a是'static)。
要修复这个问题,我们需要使用高阶生命周期约束(HRTB),让你的Abstract实现能够适配任意生命周期,而不是提前绑定到一个固定的'a。
修复后的代码
struct Owned; struct Ref<'a> { owned: &'a Owned, } trait Abstract { type Input<'a>; fn method(&self, _input: &Self::Input<'_>); } struct Concrete; impl Abstract for Concrete { type Input<'a> = Ref<'a>; fn method(&self, _input: &Self::Input<'_>) {} } // 使用HRTB约束:对任意生命周期'b,A的Input<'b>都等于Ref<'b> fn act<A>(abs: A) where for<'b> A: Abstract<Input<'b> = Ref<'b>>, { let owned = Owned {}; let obj_ref = Ref { owned: &owned }; abs.method(&obj_ref); } fn main() { act(Concrete); }
为什么这样可行?
原来的act<'a, A>约束要求A适配一个特定的、由调用者决定的生命周期'a,但函数内部的owned生命周期是临时的,无法满足这个外部指定的生命周期。
而HRTB的for<'b>语法表示:无论什么生命周期'b,A都要满足Abstract<Input<'b> = Ref<'b>>。这样当你在函数内部创建owned时,编译器会自动推导出适合的临时生命周期(正好是owned的存活期),而不会被外部的'a限制住。
这种写法完美符合你的需求:既可以在函数内部创建Owned实例,又能正确传递给Abstract的method方法。
内容的提问来源于stack exchange,提问作者Marcelo Fornet
相关产品推荐
相关产品推荐

