我是Rust的新手。我的背景是Java。我正在努力解决以下问题。
特性燃料
,它是为struct-Diesel
和struct-Gas
我还有一个特征车辆
,带有燃油
通用类型参数。车辆是为<代码>结构车实现的
最后,我想将对可能的异构特征对象的引用放入一个
Vec
中,如下所示:
let diesel_car = Car { fuel: Diesel {} };
let gas_car = Car { fuel: Gas {} };
let diesel_bus = Bus { fuel: Diesel {} };
let gas_bus = Bus { fuel: Gas {} };
let garage = vec![
&diesel_car,
&gas_car,
&diesel_bus,
&gas_bus
];
但是我得到这个编译错误:
error[E0308]: mismatched types
--> src/main.rs:63:9
|
63 | &gas_car,
| ^^^^^^^^ expected struct `Diesel`, found struct `Gas`
|
= note: expected type `&Car<Diesel>`
found reference `&Car<Gas>`
这个Vec中的引用的泛型应该是什么?它猜应该是类似于
Vec的东西
整个例子都可以在操场上看到。
附言:我显然可以从
车辆
中删除通用参数并将其替换为Box
匿名用户
不可能将不同的类型放在同一个向量中。但是,使用枚举,您可以获得所需的功能,而无需不同的类型。
因为您有两种不同的燃料,它们的枚举将如下所示:
pub enum Fuel {
Diesel,
Gas,
}
然后添加一个函数< code>efficiency来返回各种燃料的效率:
impl Fuel {
fn efficiency(&self) -> f64 {
match self {
Fuel::Diesel => 0.9,
Fuel::Gas => 0.8,
}
}
}
您现在有两种类型相同的燃油。
对车辆进行同样的操作后(你也有2个车辆的变体),你可以将不同的组合添加到同一个向量中。
这是一个完整的例子。
你可以在这里阅读枚举。
但是这个变体也没有编译,因为[编译器]想事先知道车辆的泛型类型参数。
我认为你在这里混淆了静态调度和动态调度。我认为你也混淆了你要求编译器做什么和你期望它做什么。很明显,这听起来像是你想要动态调度,但你正试图使用泛型来实现它,这是不可能的,因为泛型是一种纯粹的编译时抽象,并且总是会产生静态调度代码。“泛型”在运行时不存在,也不存在于最终的二进制文件中。如果你想要“运行时泛型”,这就是特征对象和动态调度的用途。
在Java中,我只需编写<code>列表
是,将
F:Fuel
泛型类型参数替换为dyn-Fuel
trait对象。
附言:我显然可以从
车辆
中删除通用参数并将其替换为Box
但您刚刚问了如何在Rust中实现Java等价物,Java就是这样解决这个问题的:通过使用动态调度。你不能既有蛋糕又吃。如果您想要静态调度的速度,这意味着也要接受静态调度的约束。如果这些约束对于您的程序来说太严格,那么您应该使用trait对象和动态调度。
Rust的枚举可能是最接近您想要的。它们是泛型和特质对象之间的一个很好的折衷方案,让你(几乎)拥有前者的速度,同时也让你拥有后者的灵活性。以下是您重构使用枚举的示例:
enum Fuel {
Diesel,
Gas,
}
impl Fuel {
fn efficiency(&self) -> f64 {
match self {
Fuel::Diesel => 0.9,
Fuel::Gas => 0.8,
}
}
}
enum Vehicle {
Car(Fuel),
Bus(Fuel)
}
impl Vehicle {
fn mass(&self) -> f64 {
match self {
Vehicle::Car(_) => 1000.0,
Vehicle::Bus(_) => 5000.0,
}
}
}
fn main() {
let diesel_car = Vehicle::Car(Fuel::Diesel);
let gas_car = Vehicle::Car(Fuel::Gas);
let diesel_bus = Vehicle::Bus(Fuel::Diesel);
let gas_bus = Vehicle::Bus(Fuel::Gas);
let garage = vec![
&diesel_car,
&gas_car,
&diesel_bus,
&gas_bus
];
}
游乐场
我正在Rust中编写一个带有控制台提示界面的进程内存扫描器。 我需要扫描仪类型,如winapi扫描仪或ring0驱动程序扫描仪,所以我试图实现多态性。 目前我有以下结构: 将来,除了 之外,我还会有更多扫描仪类型,因此,如果我理解正确,我应该使用特征引用 (
我正在尝试创建一个特征对象的向量,但我得到了类型不匹配。我还尝试使用代替for循环,但遇到了同样的问题。这是我真实代码的最小版本,我意识到这个例子不需要使用特征对象,但我的真实代码需要,因为列表中除了之外还有其他类型,它们也实现了。如何使用正确的类型创建以便将其传递给?
(这是我第二次尝试追踪我的确切问题。查看编辑历史记录) 我有一个简单的通用特性和两种不同的实现: 我现在想要一个包含两个实现元素的向量。正如我在这里学到的,我做: 但是编译器不同意: 一方面,这是有道理的。另一方面,我应该为写什么?我希望它是通用的,所以我不能简单地在那里放或。我可以做
我的情况是,我希望一些对象实现一个特征,比如说“基本”,而其他一些对象将实现一个特征“超级”。Super trait还必须是< code>T : Base的泛型,这样我就可以根据它所专用的Base自动实现Super的各个部分。现在,这似乎可以很好地处理下面的小例子 我的问题与我的下一个要求有关,那就是我希望能够存储实现Super的对象向量,而不管它专门用于哪个Base。我的想法是创建一个涵盖所有超
我试图获得对创建java的GoogleMap对象的引用,但我不知道如何获得这个引用。
关于一个语言被称为面向对象所需的功能,在编程社区内并未达成一致意见。Rust 被很多不同的编程范式影响,包括面向对象编程;比如第十三章提到了来自函数式编程的特性。面向对象编程语言所共享的一些特性往往是对象、封装和继承。让我们看一下这每一个概念的含义以及 Rust 是否支持他们。In my view the Gang of Four is the best book ever written on