方法
Rust 允许您将函数与新类型相关联。您可以使用“impl”块来执行此操作:
#[derive(Debug)]
struct Race {
name: String,
laps: Vec<i32>,
}
impl Race {
// No receiver, a static method
fn new(name: &str) -> Self {
Self { name: String::from(name), laps: Vec::new() }
}
// Exclusive borrowed read-write access to self
fn add_lap(&mut self, lap: i32) {
self.laps.push(lap);
}
// Shared and read-only borrowed access to self
fn print_laps(&self) {
println!("Recorded {} laps for {}:", self.laps.len(), self.name);
for (idx, lap) in self.laps.iter().enumerate() {
println!("Lap {idx}: {lap} sec");
}
}
// Exclusive ownership of self
fn finish(self) {
let total: i32 = self.laps.iter().sum();
println!("Race {} is finished, total lap time: {}", self.name, total);
}
}
fn main() {
let mut race = Race::new("Monaco Grand Prix");
race.add_lap(70);
race.add_lap(68);
race.print_laps();
race.add_lap(71);
race.print_laps();
race.finish();
// race.add_lap(42);
}
The self
arguments specify the “receiver” - the object the method acts on. There are several common receivers for a method:
- “&self”:使用不可变的共享引用从调用方借用对象。之后可以再次使用该对象。
- “&mut self”:使用唯一的可变引用从调用方借用对象。之后可以再次使用该对象。
- “self”:获取对象的所有权并将其从调用方移出。该方法会成为对象的所有者。除非明确转移对象的所有权,否则在该方法返回时,对象将被丢弃(取消分配)。具备完全所有权,不自动等同于具备可变性。
mut self
: same as above, but the method can mutate the object.- 无接收器:这将变为结构体上的静态方法。通常用于创建构造函数,按惯例被称为“new”。
This slide should take about 8 minutes.
关键点:
- 引入方法时,将方法与函数进行比较会很有帮助。
- 在某种类型(例如结构体或枚举)的实例上调用方法,第一个参数将该实例表示为“self”。
- 开发者可能会选择使用方法,以便利用方法接收器语法并让方法更有条理。通过使用方法,我们可以将所有实现代码保存在一个可预测的位置。
- 指出关键字“self”的用法,它是一种方法接收器。
- 显示它是“self: Self”的缩写术语,或许要显示结构体名称的可能用法。
- 说明“Self”是“impl”块所属类型的类型别名,可以在块中的其他位置使用。
- 指出“self”的使用方式与其他结构体一样,并且可以使用点表示法来指代各个字段。
- This might be a good time to demonstrate how the
&self
differs fromself
by trying to runfinish
twice. - Beyond variants on
self
, there are also special wrapper types allowed to be receiver types, such asBox<Self>
.