方法
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>
.