“ 根据某些定义,Rust 是面向对象的;而在其它一些定义下,Rust 又不是。”
01
—
包含数据和行为的对象
Object-oriented programs are made up of objects. An object packages both data and the procedures that operate on that data. The procedures are typically called methods or operations.
面向对象的程序是由对象组成的。一个对象包含数据和操作这些数据的程序(不是计算机程序,而是指做事情的程序)。这些程序通常被称为方法或操作。
02
—
通过封装隐藏实现细节
pub struct AveragedCollection {
list: Vec<i32>,
average: f64,
}
在上面的例子中,结构体被标记为 pub,这样其他代码就可以使用它,但是在结构体内部的字段仍然是私有的。这一点非常重要,因为我们希望平均值在列表发生改变时,会同时被更新。我们可以通过在结构体上实现 add、remove 和 average 等方法来做到这一点,参考下面的例子:
impl AveragedCollection {
pub fn add(&mut self, value: i32) {
self.list.push(value);
self.update_average();
}
pub fn remove(&mut self) -> Option<i32> {
let result = self.list.pop();
match result {
Some(value) => {
self.update_average();
Some(value)
}
None => None,
}
}
pub fn average(&self) -> f64 {
self.average
}
fn update_average(&mut self) {
let total: i32 = self.list.iter().sum();
self.average = total as f64 / self.list.len() as f64;
}
}
公有方法 add、remove 和 average 是访问或修改 AveragedCollection 实例中数据的唯一方式。当使用 add 方法为列表增加元素或使用 remove 方法从列表删除元素时,这些方法会调用私有的 update_average 方法更新 average 字段。我们保持 list 和 average 字段是私有的,因此外部代码无法直接增加或者删除列表中的元素,否则当列表改变时, average 字段可能并未更新。
03
—
继承
To many people, polymorphism is synonymous with inheritance. But it’s actually a more general concept that refers to code that can work with data of multiple types. For inheritance, those types are generally subclasses.
Rust instead uses generics to abstract over different possible types and trait bounds to impose constraints on what those types must provide. This is sometimes called bounded parametric polymorphism.
很多人将多态等同于继承。不过它是一个更为通用的概念,指代码可以用于可能包含不同数据的多种类型。对于继承来说,这些类型通常是某个类型的子类。
Rust 则通过泛型来抽象不同的类型,并通过 trait bounds 约束类型所必须包含的行为。这有时被称为“有界参数多态”。