简体   繁体   English

为什么 rust 中的关联类型需要显式生命周期注解?

[英]Why associated types in rust need explicit lifetime annotation?

I'm working with a trait which cannot be touched like this(minimized):我正在处理一个不能像这样触摸的特征(最小化):

// The associated version
trait Testable {
    type T;
    fn test_it(&self, x: Self::T) -> bool;
}

Then I try to impl it with, say, i32 :然后我尝试i32 impl它:

impl Testable for i32 {
    type T = &str;
    fn test_it(&self, x: Self::T) -> bool {
        x.is_empty()
    }
}

However, I got compiler error:但是,我收到编译器错误:

type T = &str;
         ^ explicit lifetime name needed here

The associated type Self::T is just on the input parameter of method test_it .关联类型Self::T就在方法test_it的输入参数上。 Why does the compiler claim that I have to provide lifetime annotation?为什么编译器声称我必须提供生命周期注解?

Note that if I change T to generic type like:请注意,如果我将T更改为通用类型,例如:

// The generic version
trait Testable<T> {
    fn test_it(&self, x: T) -> bool;
}

impl Testable<&str> for i32 {
    fn test_it(&self, x: &str) -> bool {
        x.is_empty()
    }
}

This time the code compiled without error.这次代码编译没有错误。

The problem is问题是

(1) why I have to provide lifetime annotation in the associated version since the type only appears at the input parameter side? (1) 为什么我必须在关联版本中提供生命周期注释,因为类型只出现在输入参数端?

(2) Why the generic version compiled? (2) 为什么要编译通用版? Are there any deep differences between the two versions?这两个版本之间有什么深刻的区别吗?

The difference is that the associated type is chosen by the trait, whereas the generic parameter is chosen by the caller.区别在于关联类型由特征选择,而泛型参数由调用者选择。 So with this code:所以用这段代码:

impl Testable for i32 {
    type T = &str;
    fn test_it(&self, x: Self::T) -> bool {
        x.is_empty()
    }
}

The compiler needs to be able to know everything about T without looking at any other part of the code.编译器需要能够在不查看代码的任何其他部分的情况下了解有关T的所有信息。 But it can't: there is no way to know the lifetime of the reference just by looking at this code (btw the only lifetime that can work here is 'static ).但它不能:仅通过查看这段代码无法知道引用的生命周期(顺便说一下,这里唯一可以工作的生命周期是'static )。

On the other hand with this code:另一方面,使用此代码:

impl Testable<&str> for i32 {
    fn test_it(&self, x: &str) -> bool {
        x.is_empty()
    }
}

&str is an incomplete type since it's missing the lifetime, but that's ok because the type will be filled-in on the call site (like all template parameters). &str是一个不完整的类型,因为它缺少生命周期,但这没关系,因为该类型将在调用站点上填写(就像所有模板参数一样)。

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

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