为什么终身省略对特征不起作用

Why doesn't lifetime elision work for traits

我想创建我自己的特征,它应该基于 f32 的索引产生 i32。我尝试了以下方法,似乎确实有效:

use std::ops::Index;
// trait by value
pub trait MyTrait:
    Index<f32, Output=i32> {
}

虽然按值传递 f32 可能是个好主意,但对于更复杂的类型,我宁愿传递对值的引用,所以我尝试了以下操作:

// trait by reference, not compiling
pub trait MyTrait:
    Index<&f32, Output=i32> {
}

包括这个定义给了我一个 error[E0106]: missing lifetime specifier。我得到了这个变体:

// trait by reference, compiling
pub trait MyTrait<'a>:
    Index<&'a f32, Output=i32> {
}

问题是:虽然这种方法有效,但它意味着任何实现 MyTrait 的类型都需要一个明确的生命周期参数。

然而,这似乎是不必要的:如果我为自己的结构实现 Index 特性,我就不需要任何生命周期:

struct Test {
  value: i32
}

impl Index<&f32> for Test {
  type Output = i32;

  fn index(&self, _key: &f32) -> &Self::Output {
    &self.value
  }
}

问题一:为什么在trait的定义中需要额外的lifetime,为什么不能省略?

问题 2:我可以通过避免引入生命周期的方式来定义特征吗?

Why do I need the additional lifetime in the definition of the trait, why can't it be elided?

Lifetime elision仅适用于函数签名。所以不,它不适用于您的特征定义。

Can I define the trait in such a way as to avoid having to introduce the lifetime?

当然,您可以像 std::ops::Index 那样使用泛型参数:

use std::ops::Index;
pub trait MyTrait<T>: Index<T, Output = i32> {}

struct Test {
    value: i32,
}

impl Index<&f32> for Test {
    type Output = i32;

    fn index(&self, _key: &f32) -> &Self::Output {
        &self.value
    }
}

impl MyTrait<&f32> for Test {}

据我所知(我不是 100% 确定,文档对此相当沉默),这个:

impl Index<&f32> for Test { /* ... */ }

是shorthand为此:

impl <'a> Index<&'a f32> for Test { /* ... */ }

换句话说,你实现了 any 生命周期的特性。

类似地,您可以要求在您的绑定中的任何生命周期内实现该特征:

pub trait MyTrait:
    for<'a> Index<&'a f32, Output = i32> {
  // ...
}