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)
这是什么意思?看来不是特质遗传。
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
可以是任何东西,所以实现Display
forA<'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)
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)