简体   繁体   English

为什么特质实现不编译为结构,但编译为对结构的引用?

[英]Why doesn't a trait implementation compile for a struct, but it compiles for a reference to the struct?

To answer one of my previous questions ( How to implement a generic trait with a generic type implementing Iterator? ), this chunk of code was given to me: 为了回答我以前的问题之一( 如何用实现Iterator的通用类型实现通用特征? ),将这段代码提供给我:

pub trait Vector {
    type Item;
    type Iter: Iterator<Item = Self::Item>;

    // several functions
    fn iter(&self) -> Self::Iter;
}

pub struct VectorImplementation1<T> {
    numbers: Vec<T>,
}

impl<'a, T> Vector for &'a VectorImplementation1<T> {
    type Item = &'a T;
    type Iter = std::slice::Iter<'a, T>;

    fn iter(&self) -> Self::Iter {
        self.numbers.iter()
    }
}

fn main() {}

I see that the trait is implemented for a reference of struct, and it doesn't compile if I use only a struct. 我看到该特征是为引用struct而实现的,如果仅使用struct,则无法编译。 Can someone explain why? 有人可以解释为什么吗?

The problem here, as mentioned by the compiler error, is that the lifetime 'a has no reason to be there if it is implemented like so: 正如编译器错误所提到的,这里的问题是,如果按如下方式实现,则生存期'a没有理由存在:

impl<'a, T> Vector for VectorImplementation1<T> {
    /**/
}
error[E0207]: the lifetime parameter `'a` is not constrained by the impl 
trait, self type, or predicates
  --> src/main.rs:13:6
   |
13 | impl<'a, T> Vector for VectorImplementation1<T> {
   |      ^^ unconstrained lifetime parameter

Because the compiler only looks at the definition, and not the body in this case. 因为在这种情况下,编译器仅查看定义,而不查看主体。 A different approach, which probably wasn't mentioned earlier for simplicity, is the following: 下面是一种不同的方法,为简单起见,可能之前没有提到过:

pub trait Vector<'a> {
    type Item: 'a;
    type Iter: Iterator<Item = Self::Item> + 'a;

    // several functions
    fn iter(&'a self) -> Self::Iter;
}

pub struct VectorImplementation1<T> {
    numbers: Vec<T>,
}

impl<'a, T: 'a> Vector<'a> for VectorImplementation1<T> {
    type Item = &'a T;
    type Iter = std::slice::Iter<'a, T>;

    fn iter(&'a self) -> Self::Iter {
        self.numbers.iter()
    }
}

impl<'a, T: 'a> Vector<'a> for &'a VectorImplementation1<T> {
    type Item = &'a T;
    type Iter = std::slice::Iter<'a, T>;

    fn iter(&'a self) -> Self::Iter {
        self.numbers.iter()
    }
}

In this case, we move the lifetime to the trait, so that the trait can "use" the lifetime, and therefore validate our use of the trait implementation. 在这种情况下,我们将生存期移至特征,以便该特征可以“使用”生存期,从而验证我们对特征实现的使用。 But as I mentioned earlier, this has the added complexity of needing to understand the lifetimes attached to this trait, reducing readability. 但是,正如我前面提到的,这增加了需要了解与该特征相关的生存期的复杂性,从而降低了可读性。

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

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