Rust支持trait继承,具体如下:
pub trait A {}
pub trait B: A {}
B: A
的含义是如果某种类型 T
实现了 B
,那么它也需要实现 A
中所有的方法。
但今天我看到了以下代码:
trait Display: 'static {
fn print(&self);
}
这是什么意思?它似乎不是特性继承。
'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!() }
}
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
}
trait B: A
的意思只是“如果你实现了B,你也必须实现A”。对于trait的用户来说,这与继承具有类似的效果,因为他们可以要求B
并确保也得到了A
。但是,实现B的人没有继承,他们必须另外(而且是分别)实现A。在这种情况下,Display:'static
表示作为Display
的用户,您可以确定实现它的类型具有'static
生命周期限制,这意味着它不会借用非静态数据。 - user4815162342