当我们让一个特性继承 'static 时,这意味着什么?

5

Rust支持trait继承,具体如下:

pub trait A {}
pub trait B: A {}

B: A 的含义是如果某种类型 T 实现了 B,那么它也需要实现 A 中所有的方法。

但今天我看到了以下代码:

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

这是什么意思?它似乎不是特性继承。

“继承”可能不是这里的正确思维模型。trait B: A 的意思只是“如果你实现了B,你也必须实现A”。对于trait的用户来说,这与继承具有类似的效果,因为他们可以要求B并确保也得到了A。但是,实现B的人没有继承,他们必须另外(而且是分别)实现A。在这种情况下,Display:'static表示作为Display的用户,您可以确定实现它的类型具有'static生命周期限制,这意味着它不会借用非静态数据。 - user4815162342
2个回答

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!() }
}

将会产生以下错误:

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

这是因为 'a 可以是任何类型,因此为 A<'a> 实现 Display 意味着它也被实现为非静态实例,这是不合法的。

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

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

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

要求满足特质的要求,并且实现是有效的(注意:这里不需要'a,你可以只使用impl ... for A<'static>,我展示它是为了保持一致性)。

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

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

impl Display for A {
    fn print(&self) { todo!() }
}

4

Rust没有继承。

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

在您这种情况下,约束是生命周期边界

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

假设您有这种类型:

struct S<'a> {
    s: &'a str,
}

那么你只能将 trait 实现为 '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
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接