当前位置: 首页 > 知识库问答 >
问题:

通用特征对象的向量

丰俊艾
2023-03-14

(这是我第二次尝试追踪我的确切问题。查看编辑历史记录)

我有一个简单的通用特性和两种不同的实现:

pub trait MyTrait<T=Self> where T: MyTrait {
}

struct Impl1;
impl MyTrait for Impl1 {
}

struct Impl2;
impl MyTrait for Impl2 {
}

我现在想要一个包含两个实现元素的向量。正如我在这里学到的,我做:

fn foo() {
    let mut traits: Vec<Box<MyTrait>> = Vec::new();
    traits.push(Box::new(Impl1{}));
    traits.push(Box::new(Impl2{}));
}

但是编译器不同意:

error[E0393]: the type parameter `T` must be explicitly specified
  --> src/main.rs:25
   |
25 |     let mut traits: Vec<Box<MyTrait>> = Vec::new();
   |                             ^^^^^^^ missing reference to `T`
   |
   = note: because of the default `Self` reference, type parameters must be specified on object types

一方面,这是有道理的。另一方面,我应该为T写什么?我希望它是通用的,所以我不能简单地在那里放IMP1IMP2。我可以做Vec

编辑

上面的代码是最小的失败代码,下面是一个稍微少一点的实现:

enum MyEnum<T: MyTrait> {
    A(T),
    B
}

pub trait MyTrait<T=Self> where T: MyTrait {
    fn do_stuff(self) -> MyEnum<T>;
}

struct Impl1;
impl MyTrait for Impl1 {
    fn do_stuff(self) -> MyEnum<Impl1> {
        MyEnum::A(self)
    }
}

struct Impl2;
impl MyTrait for Impl2 {
    fn do_stuff(self) -> MyEnum<Impl2> {
        MyEnum::B
    }
}

每个MyTrait对象都会消耗自身,并可能导致一个MyEnum::a,其中包含另一个MyTrait对象,或者导致一个MyEnum::B


共有1个答案

锺离浩慨
2023-03-14

泛型的东西不管特征、类型或函数是否不是可以处理的代码,而仅仅是替换它们时生成的代码模板。因此它们不是“对象安全的”,也就是说,您不能将它们用于动态引用和智能指针的类型。您只能使用它们的特定实例。

MyTrait是通用的,所以你不能有

您确实有该参数的默认值,但Self是特殊的,因为Self是实现trait的类型,因此仅在impl定义中有意义。但不是在您尝试声明Vec的自由函数中

同样由于自我是多么特别,Impl1的MyTrait被解压以impel MyTrait

你需要一个具体的,这是非通用的,动态多态性的特征。

 类似资料:
  • 我正在尝试创建一个特征对象的向量,但我得到了类型不匹配。我还尝试使用代替for循环,但遇到了同样的问题。这是我真实代码的最小版本,我意识到这个例子不需要使用特征对象,但我的真实代码需要,因为列表中除了之外还有其他类型,它们也实现了。如何使用正确的类型创建以便将其传递给?

  • 考虑以下代码: 当我尝试推送<code>cat</code>时,编译器告诉我<code>v</code>是<code>动物</code>的向量(类型不匹配) 那么,如何制作一个属于trait的对象向量,并在每个元素上调用相应的trait方法呢?

  • 本文向大家介绍Java面向对象的三大特征,包括了Java面向对象的三大特征的使用技巧和注意事项,需要的朋友参考一下   java面向对象的三大特征:“封装、继承、多态”。更多Java技术知识,请登陆疯狂软件教育官网。微信搜索微信号:疯狂软件,参加2015年优惠活动,有机会获得优惠劵和代金劵。   以本文为例,User类中的变量为私有变量,只能通过创建对象(此时构造方法自动调用)来赋值。   外界只

  • 关于一个语言被称为面向对象所需的功能,在编程社区内并未达成一致意见。Rust 被很多不同的编程范式影响,包括面向对象编程;比如第十三章提到了来自函数式编程的特性。面向对象编程语言所共享的一些特性往往是对象、封装和继承。让我们看一下这每一个概念的含义以及 Rust 是否支持他们。In my view the Gang of Four is the best book ever written on

  • 我正在Rust中编写一个带有控制台提示界面的进程内存扫描器。 我需要扫描仪类型,如winapi扫描仪或ring0驱动程序扫描仪,所以我试图实现多态性。 目前我有以下结构: 将来,除了 之外,我还会有更多扫描仪类型,因此,如果我理解正确,我应该使用特征引用 (