Generics 如何创建Rust中泛型特征对象的Vec引用?

Generics 如何创建Rust中泛型特征对象的Vec引用?,generics,rust,polymorphism,traits,trait-objects,Generics,Rust,Polymorphism,Traits,Trait Objects,我是个新手。我的背景是Java。我正在努力解决以下问题 我有一个trait Fuel,用于struct Diesel和struct Gas 我还有一个trait Vehicle,带有Fuel通用类型参数。车辆是为struct Car和struct Bus实现的 最后,我想将对可能的异构特征对象的引用放入一个Vec,如下所示: pub enum Fuel { Diesel, Gas, } 让柴油车=汽车{燃料:柴油{}; 让gas_car=car{燃料:gas{}; 让柴油车=公

我是个新手。我的背景是Java。我正在努力解决以下问题

  • 我有一个
    trait Fuel
    ,用于
    struct Diesel
    struct Gas
  • 我还有一个
    trait Vehicle
    ,带有
    Fuel
    通用类型参数。车辆是为
    struct Car
    struct Bus
    实现的
  • 最后,我想将对可能的异构特征对象的引用放入一个
    Vec
    ,如下所示:

    pub enum Fuel {
        Diesel,
        Gas,
    }
    
    让柴油车=汽车{燃料:柴油{};
    让gas_car=car{燃料:gas{};
    让柴油车=公共汽车{燃料:柴油{};
    让gas_bus=bus{fuel:gas{};
    让车库=vec![
    &柴油车,
    &汽油车,
    &柴油巴士,
    &燃气公共汽车
    ];
    
    但我得到了这个编译错误:

    错误[E0308]:类型不匹配
    -->src/main.rs:63:9
    |
    63 |和汽油车,
    |^^^^^^^^^^应为结构“柴油机”,找到结构“天然气”`
    |
    =注意:预期类型`&Car`
    找到了参考`&Car`
    

    此Vec中引用的一般类型应该是什么?它猜应该是类似于
    Vec
    。但是这个变体也没有编译,因为它想事先知道
    车辆的通用类型参数。在Java中,我只写
    List,不可能在同一个向量中放置不同的类型。
    但是,使用enum,您可以在不需要不同类型的情况下获得所需的功能

    由于您有两种不同的燃料,它们的枚举将如下所示:

    pub enum Fuel {
        Diesel,
        Gas,
    }
    
    然后添加一个函数
    efficiency
    ,以返回每个燃油变量的效率:

    impl Fuel {
        fn efficiency(&self) -> f64 {
            match self {
                Fuel::Diesel => 0.9,
                Fuel::Gas => 0.8,
            }
        }
    }
    
    您现在有两种相同类型的燃油

    对车辆执行相同操作后(您也有两种变体),可以将各种组合添加到同一矢量

    但是这个变量也没有编译,因为[编译器]想事先知道
    Vehicle
    的泛型类型参数

    我认为您在这里混淆了静态调度和动态调度。我认为你也混淆了你要求编译器做什么和你期望它做什么。听起来很明显,您想要动态分派,但是您试图使用泛型来实现它,这是不可能的,因为泛型是纯编译时抽象,并且总是生成静态分派代码。“泛型”在运行时不存在,并且不存在于最终二进制文件中。如果您想要“运行时泛型”,这就是trait对象和动态分派的用途


    在Java中,我只需编写
    list就我所知,泛型Foo是一种与Foo完全不同的类型,而Foo根本不是一种类型。所以我认为没有戴恩,这是不可能的。谢谢。与我在实践中想要的相比,我的例子过于简化了。实际上,a希望能够灵活地添加新燃料和车辆,因此使用Enum可能不是解决此问题的最佳方法。此外,与使用动态调度相比,它是否有任何性能提升?实际上,我们只是在
    match
    表达式中复制了动态调度的逻辑,不是吗?使用
    match
    可以省去对vtable指针的引用,因此我相信它比常规动态调度更快。此外,Java对所有内容都使用动态分派和垃圾收集。所以,如果Java足够快,可以满足您的需求,那么毫无疑问Rust也会足够快,即使您不使用静态分派。