简体   繁体   English

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

[英]Why doesn't lifetime elision work for traits

I would like to create my own trait, which should yield a i32 based onindexing with a f32 .我想创建我自己的特征,它应该基于使用f32的索引产生i32 I tried the following, which does seem to work:我尝试了以下方法,这似乎确实有效:

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

While passing an f32 by value may be a good idea, for more complicated types I would rather pass a reference to the value instead, so I tried the following:虽然按值传递f32可能是个好主意,但对于更复杂的类型,我宁愿传递对该值的引用,因此我尝试了以下操作:

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

Including this definition gives me an error[E0106]: missing lifetime specifier .包括这个定义给了我一个error[E0106]: missing lifetime specifier I got this variant working:我让这个变体工作:

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

Problem is: While this approach works, it means any type implementing MyTrait needs an explicit lifetime argument.问题是:虽然这种方法有效,但它意味着任何实现MyTrait类型MyTrait需要一个显式的生命周期参数。

However, this seems rather unnecessary: If I implement the Index trait for my own struct I don't need any lifetimes:但是,这似乎没有必要:如果我为自己的结构实现Index trait,则不需要任何生命周期:

struct Test {
  value: i32
}

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

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

Question 1: Why do I need the additional lifetime in the definition of the trait, why can't it be elided?问题1:为什么我在trait的定义中需要额外的生命周期,为什么不能省略?

Question 2: Can I define the trait in such a way as to avoid having to introduce the lifetime?问题 2:我能否以一种避免引入生命周期的方式定义 trait?

Why do I need the additional lifetime in the definition of the trait, why can't it be elided?为什么在 trait 的定义中需要额外的生命周期,为什么不能省略呢?

Lifetime elision is only applied to function signature .终身省略仅适用于函数签名 So no it won't work for your trait definition.所以不,它不适用于您的特征定义。

Can I define the trait in such a way as to avoid having to introduce the lifetime?我是否可以通过避免引入生命周期的方式来定义特征?

Certainly, you can use generic parameter just as whatstd::ops::Index does:当然,您可以像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 {}

As far as I can tell (and I'm not 100% sure, the docs are rather silent on this), this:据我所知(我不是 100% 肯定,文档对此相当沉默),这个:

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

is shorthand for this:是这个的简写:

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

In other words, you implement the trait for any lifetime.换句话说,您可以在任何生命周期内实现 trait。

Analogously, you can require that the trait is implemented for any lifetime in your bound:类似地,您可以要求在您的边界内的任何生命周期内实现 trait:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM