当我在这段代码中不包括+ 'static时,rustc会抱怨。为什么?
// adapted from rust-analyzer https://github.com/rust-analyzer/rust-analyzer
trait Upcast<T: ?Sized> {
fn upcast(&self) -> &T;
}
trait DefDatabase {}
trait HirDatabase: Upcast<dyn DefDatabase> {}
struct RootDatabase{}
impl Upcast<dyn DefDatabase> for RootDatabase {
fn upcast(&self) -> &(dyn DefDatabase + 'static) {
&*self
}
}`impl` item signature doesn't match `trait` item signature
expected `fn(&RootDatabase) -> &(dyn DefDatabase + 'static)`
found `fn(&RootDatabase) -> &dyn DefDatabase`
the lifetime requirements from the `impl` do not correspond to the
requirements in the `trait`
verify the lifetime relationships in the `trait` and `impl` between the
`self` argument, the other inputs and its output为什么'static生命周期是必需的?
看起来dyn对于这个例子是必不可少的。rustc没有抱怨这一进步,也没有提到'static
impl Upcast<RootDatabase> for RootDatabase {
fn upcast(&self) -> &Self {
self
}
}发布于 2022-01-14 23:14:04
您需要显式地声明属性对象&'dyn DefDatabase的生存期,这样借入检查器就可以知道指针后面的结构所持有的任何引用的生存期。如果您不定义'static,则它是默认的,否则无法从上下文中确定它。有关更多信息,请参见生锈语言参考中的默认特征对象生存期。
将生命周期添加到Upcast特性定义中,可以让您放弃'static。
trait Upcast<'a, T: ?Sized + 'a> {
fn upcast(&self) -> &T; // 'a is not necessary here because the generic `T` may or may not be a trait object
}
trait DefDatabase {}
struct RootDatabase{}
impl DefDatabase for RootDatabase {}
impl<'a> Upcast<'a, dyn DefDatabase> for RootDatabase {
fn upcast(&self) -> &(dyn DefDatabase + 'a) { // now we can replace 'static with 'a
&*self
}
}
impl<'a> Upcast<'a, RootDatabase> for RootDatabase {
fn upcast(&self) -> &Self { // &Self is not a trait object, so no trait object lifetime is necessary
self
}
}编辑
应该注意的是,此生存期不是对属性对象的引用的生存期,可以单独声明,这也是为什么必须用括号消除生存期的原因。
impl<'a> Upcast<'a, dyn DefDatabase> for RootDatabase {
fn upcast<'b>(&'b self) -> &'b (dyn DefDatabase + 'a) { // 'b is elided
&*self
}
}https://stackoverflow.com/questions/70717413
复制相似问题