将生命周期参数限制在函数的参数范围内

Restrict lifetime parameter to scope of parameters of a function

考虑以下示例

trait MyTrait<'a> {
    type N: 'a;

    fn func(&'a self) -> Self::N;
}

fn myfunc<'a, T: 'a + MyTrait<'a>>(g: T) {
    g.func();
}

fn main() {}

编译这个小程序失败:

error[E0597]: `g` does not live long enough
 --> src/main.rs:8:5
  |
8 |     g.func();
  |     ^ borrowed value does not live long enough
9 | }
  | - borrowed value only lives until here
  |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 7:1...
 --> src/main.rs:7:1
  |
7 | fn myfunc<'a, T: 'a + MyTrait<'a>>(g: T) {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

据我了解,生命周期参数'a不受限制,可以是任意的。但是g是一个参数,它的生命周期只是函数作用域,所以不满足func.

方法定义中的生命周期条件'a

我真正想要的是关联类型N总是限制在selfMyTrait的生命周期内。这就是为什么我想出了 MyTrait 的显式生命周期参数 'a。我希望函数 myfunc 起作用,即 'a 应该以某种方式限制在参数 g.

的生命周期内

解决这个问题的"correct"方法是什么?

一个非常简单的例子是

struct MyPtr<'a> {
    x: &'a usize,
}

struct MyStruct {
    data: Vec<usize>,
}

impl<'a> MyTrait<'a> for MyStruct {
    type N = MyPtr<'a>;

    fn func(&'a self) -> Self::N {
        MyPtr { x: &self.data[0] }
    }
}

请注意,这当然是极其简化的。这个想法是 N 总是包含对 MyTrait 中包含的内容的引用,因此永远不会超过 MyTrait.

你想要的不是绑定泛型生命周期,而是允许 "any" 生命周期:

fn myfunc<T: for<'a> MyTrait<'a>>(g: T) {
    g.func();
}

playground 中的完整示例。

最好的解释来源是