当我们让一个特质继承“static”时,这意味着什么?

Sea*_*ene 5 static traits lifetime rust

Rust 支持特征继承,如下:

pub trait A {}
pub trait B: A {}
Run Code Online (Sandbox Code Playgroud)

B: A意味着如果某个类型T实现了B,它还需要实现 中的所有方法A

但今天我看到下面的代码:

trait Display: 'static {
    fn print(&self);
}
Run Code Online (Sandbox Code Playgroud)

这是什么意思?看来不是特质遗传。

Mas*_*inn 6

Rust 支持特征继承,如下 [...] B: A 意味着如果某个类型 T 实现了 B,它也需要实现 A 中的所有方法。

从技术上讲,这不是继承而是需求。它是一种与函数中的特征并不完全不同的特征:它限制 B 实现的类型只能是 A 已经实现的类型。

随着措辞的改变,第二个版本更容易理解:它是一个生命周期界限,这意味着它将 B 可实现的类型限制为仅具有'static生命周期的类型,这意味着如果您尝试在类型上实现 B,那么必须要么根本没有生命周期,要么有'static生命周期(或者实现必须有生命周期限制,即仅适用于该类型的某些用途)。

您可以看到,如果您尝试在生命周期通用结构上实现该特征:

struct A<'a>(&'a str);
trait Display: 'static {
    fn print(&self);
}

impl <'a>Display for A<'a> {
    fn print(&self) { todo!() }
}
Run Code Online (Sandbox Code Playgroud)

将产生

错误[E0478]:不满足生命周期限制

那是因为'a可以是任何东西,所以实现DisplayforA<'a>意味着它也可以为非'static实例实现,这是无效的。

通过在 impl 上添加相关的生命周期限制,从而将实现限制为A<'static>实例:

struct A<'a>(&'a str);
trait Display: 'static {
    fn print(&self);
}

impl <'a: 'static>Display for A<'a> {
    fn print(&self) { todo!() }
}
Run Code Online (Sandbox Code Playgroud)

满足特征的要求,并且 impl 是有效的(注意:'a这里没有必要impl ... for A<'static>,您可以只是这样做,我展示它是为了规律性)。

如果你的结构没有生命周期,它默认工作,因为没有生命周期 ~ 'static

struct A(String);
trait Display: 'static {
    fn print(&self);
}

impl Display for A {
    fn print(&self) { todo!() }
}
Run Code Online (Sandbox Code Playgroud)


Den*_*ret 4

Rust 没有继承。

它有一种定义约束的方法。例如,一个特征可能被限制为仅由实现另一个特征的类型来实现。

在您的情况下,约束是一生的约束

为了实现您的Display特征,对象可以包含引用,但在这种情况下,它们的生命周期必须遵守此约束。

假设您有这种类型:

struct S<'a> {
    s: &'a str,
}
Run Code Online (Sandbox Code Playgroud)

那么你就不能在任何生命周期内实现该特征,而只能在'static.

impl Display for S<'static> {
    fn print(&self){}
}

fn main() {
    let s1 = "test";
    let a = S { s: s1 };
    a.print(); // compiles

    let s2 = "test".to_string();
    let a = S { s: &s2 };
    a.print(); // doesn't compile because s doesn't live long enough
}

Run Code Online (Sandbox Code Playgroud)