gpt4 book ai didi

rust - 为什么向 trait 添加泛型类型会影响 trait 对象和关联类型的生命周期?

转载 作者:行者123 更新时间:2023-12-03 11:37:30 26 4
gpt4 key购买 nike

我有以下代码:

trait T<GT> {
type AT;

fn foo(&self);
}

struct AbstractT<GT, AT> {
t: Box<dyn T<GT, AT = AT>>,
}

impl<GT, AT> T<GT> for AbstractT<GT, AT> {
type AT = AT;

fn foo(&self) {
self.t.foo();
}
}

fn boxed_abstract<GT, TT: T<GT> + 'static>(tt: TT) -> Box<dyn T<GT, AT = TT::AT>> {
Box::new(AbstractT { t: Box::new(tt) })
}

playground

这会引发这些错误:

error[E0310]: the associated type `<TT as T<GT>>::AT` may not live long enough
--> src/lib.rs:20:5
|
20 | Box::new(AbstractT { t: Box::new(tt) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<TT as T<GT>>::AT: 'static`...
note: ...so that the type `AbstractT<GT, <TT as T<GT>>::AT>` will meet its required lifetime bounds
--> src/lib.rs:20:5
|
20 | Box::new(AbstractT { t: Box::new(tt) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0310]: the parameter type `GT` may not live long enough
--> src/lib.rs:20:5
|
19 | fn boxed_abstract<GT, TT: T<GT> + 'static>(tt: TT) -> Box<dyn T<GT, AT = TT::AT>> {
| -- help: consider adding an explicit lifetime bound...: `GT: 'static`
20 | Box::new(AbstractT { t: Box::new(tt) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `AbstractT<GT, <TT as T<GT>>::AT>` will meet its required lifetime bounds
--> src/lib.rs:20:5
|
20 | Box::new(AbstractT { t: Box::new(tt) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


如果我删除 GT从任何地方,它都编译得很好,但使用 GT它因一堆生命周期错误而失败。似乎 GT 的存在不应影响 dyn T 的生命周期或 T::AT (因为它没有在它们中使用),但显然确实如此。同样, dyn T 的生命周期不应依赖 GT 的生命周期或 AT但显然确实如此。

我错过了什么还是终身推理问题?

最佳答案

你可能会遗漏一些东西。 Rust 自动推断 trait 对象的生命周期,在盒装 trait 对象的情况下,自动推断的生命周期为 'static .例如,这是 Rust 编译器在查看您的代码时看到的:

trait T<GT> {
type AT;

fn foo(&self);
}

struct AbstractT<GT, AT> {
// notice the added "+ 'static" below
t: Box<dyn T<GT, AT = AT> + 'static>,
}

impl<GT, AT> T<GT> for AbstractT<GT, AT> {
type AT = AT;

fn foo(&self) {
self.t.foo();
}
}

// notice the added "+ 'static" in the return type
fn boxed_abstract<GT, TT: T<GT> + 'static>(tt: TT) -> Box<dyn T<GT, AT = TT::AT> + 'static> {
Box::new(AbstractT { t: Box::new(tt) })
}

为了让它编译,我们只需要添加更明确的 'static所有泛型类型的界限,如下所示:

trait T<GT> {
type AT;

fn foo(&self);
}

struct AbstractT<GT, AT> {
t: Box<dyn T<GT, AT = AT>>,
}

impl<GT, AT> T<GT> for AbstractT<GT, AT> {
type AT = AT;

fn foo(&self) {
self.t.foo();
}
}

fn boxed_abstract<GT, TT>(tt: TT) -> Box<dyn T<GT, AT = TT::AT>>
where TT: T<GT> + 'static, GT: 'static
{
Box::new(AbstractT { t: Box::new(tt) })
}

playground

我们需要所有这些的原因 'static bounds 很简单:一个容器类型只能被 'static 绑定(bind)。如果它里面的所有类型都被 'static 绑定(bind)以此类推。

进一步阅读:
  • Default Trait Object Lifetimes

  • 更新

    如果您不喜欢 'static您可以提出的要求 AbstractT通过向其类型添加显式生命周期注释来实现通用生命周期,如下所示:

    trait T<GT> {
    type AT;

    fn foo(&self);
    }

    struct AbstractT<'a, GT, AT> {
    t: Box<dyn T<GT, AT = AT> + 'a>,
    }

    impl<'a, GT, AT> T<GT> for AbstractT<'a, GT, AT> {
    type AT = AT;

    fn foo(&self) {
    self.t.foo();
    }
    }

    fn boxed_abstract<'a, GT, TT>(tt: TT) -> Box<dyn T<GT, AT = TT::AT> + 'a>
    where TT: T<GT> + 'a, GT: 'a
    {
    Box::new(AbstractT { t: Box::new(tt) })
    }

    playground

    关于rust - 为什么向 trait 添加泛型类型会影响 trait 对象和关联类型的生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61881845/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com