Rust中trait用Self时报借值生命周期不足但指定类型正常的原因
问题原因
第一段代码编译失败的核心是生命周期约束不匹配
- 为
&[i32]实现Passabletrait时,Self类型实际是带生命周期标注的&'c [i32],这个生命周期'c由impl的调用方决定,默认推导的生命周期长度会超过call方法本身的作用域。 - 此时
call方法的泛型约束F: Fn(Self)等价于F: Fn(&'c [i32]),要求传入的闭包必须接受生命周期为'c的切片引用。 - 而
call方法内部创建的vec是局部变量,生命周期仅到方法执行结束,对应的引用&vec的生命周期远短于要求的'c,不满足闭包的参数约束,因此编译器报存活时间不足的错误。
第二段代码可正常编译的原因是触发了高阶生命周期自动适配
- 当你把约束固定写为
F: Fn(&[i32])时,Rust会自动为闭包约束添加高阶trait bound(HRTB),等价于F: for<'a> Fn(&'a [i32])。 - 该约束的含义是:闭包可以接受任意生命周期的切片引用,哪怕生命周期极短也能适配。
- 局部变量
vec的引用完全符合这个约束要求,因此可以正常编译通过。
修复方案
只需要给第一段代码的trait定义补充高阶trait bound,明确闭包支持任意生命周期的Self参数即可,修改后可正常编译的代码如下:
trait Passable: Sized { // 用for<'a>声明闭包支持任意生命周期的Self参数 fn call<F: for<'a> Fn(Self)>(f: F); } impl Passable for &[i32] { fn call<F: for<'a> Fn(Self)>(f: F) { let vec = vec![1, 2, 3]; f(&vec); } }
内容的提问来源于stack exchange,提问作者dphilipson
相关产品推荐
相关产品推荐

