【问题标题】:How can I create a variable to a trait with an associated type in Rust?如何在 Rust 中为具有关联类型的特征创建变量?
【发布时间】:2023-02-23 22:45:30
【问题描述】:

我想创建一个包含特征的变量。编译时特征实现是未知的。因此,我需要一个特征对象。这适用于“正常”特征,但不适用于特征具有关联类型的情况。

为什么?让AssTrait 成为关联类型的特征,AssTraitImpl 成为实现该特征的结构(参见下面的示例)。现在,AssTraitImpl 实例的特征对象可以指向表示为 AssTraitImpl 实现的方法的 vtable。还是我错了?

例子

下面的代码不起作用。然而,如果我们从特征中删除关联类型。

trait AssTrait {
    type Item;
}

struct AssTraitImpl {
}

impl AssTrait for AssTraitImpl {
    type Item = i32;
}

fn main() {
    let var: &dyn AssTrait;
}

我收到此错误消息:

error[E0191]: the value of the associated type `Item` (from trait `AssTrait`) must be specified
  --> src/main.rs:20:20
   |
9  |     type Item;
   |     --------- `Item` defined here
...
20 |     let var : &dyn AssTrait;
   |                    ^^^^^^^^ help: specify the associated type: `AssTrait<Item = Type>`

【问题讨论】:

  • 如果您告诉 Rust 关联类型是什么具体类型,它也会起作用(请参阅错误消息)。这也行得通:let var: &amp;dyn AssTrait&lt;Item = i32&gt;

标签: rust associated-types trait-objects


【解决方案1】:

由于类型直到运行时都是未知的,因此关联类型也是如此。这就是为什么当特征具有关联类型时 Rust 不允许特征对象,除非关联类型是固定的。

let var: &dyn AssTrait<Item = i32>;

这现在可以工作了,因为 Rust 编译器知道 Item 的类型。但是,它强制您使用的所有实现也都具有 Item = i32

您也可以通过为关联类型使用特征对象来使其更加灵活:

trait ItemBehavior {

}

let var: &dyn AssTrait<Item = dyn ItemBehavior>;

// Or, depending on usage, perhaps:
let var: &dyn AssTrait<Item = &dyn ItemBehavior>;
// Or maybe:
let var: &dyn AssTrait<Item = Box<dyn ItemBehavior>>;

现在您可以为每个可能的关联类型实现 ItemBehaviour,在使用该类型时为其提供您需要的任何方法或约束。

【讨论】:

    猜你喜欢
    • 2020-03-31
    • 2022-11-23
    • 2020-02-29
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多