首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么从属性对象的impl中的方法返回的引用需要“静态生存期”?

为什么从属性对象的impl中的方法返回的引用需要“静态生存期”?
EN

Stack Overflow用户
提问于 2022-01-14 22:52:41
回答 1查看 352关注 0票数 2

当我在这段代码中不包括+ 'static时,rustc会抱怨。为什么?

代码语言:javascript
复制
// 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
    }
}
代码语言:javascript
复制
`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

代码语言:javascript
复制
impl Upcast<RootDatabase> for RootDatabase {
    fn upcast(&self) -> &Self {
        self
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-14 23:14:04

您需要显式地声明属性对象&'dyn DefDatabase的生存期,这样借入检查器就可以知道指针后面的结构所持有的任何引用的生存期。如果您不定义'static,则它是默认的,否则无法从上下文中确定它。有关更多信息,请参见生锈语言参考中的默认特征对象生存期

将生命周期添加到Upcast特性定义中,可以让您放弃'static

代码语言:javascript
复制
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
    }
}

编辑

应该注意的是,此生存期不是对属性对象的引用的生存期,可以单独声明,这也是为什么必须用括号消除生存期的原因。

代码语言:javascript
复制
impl<'a> Upcast<'a, dyn DefDatabase> for RootDatabase {
    fn upcast<'b>(&'b self) -> &'b (dyn DefDatabase + 'a) { // 'b is elided
        &*self
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70717413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档