方法

Rust 允许您将函数与新类型相关联。您可以使用“impl”块来执行此操作:

  1. #[derive(Debug)]
  2. struct Race {
  3. name: String,
  4. laps: Vec<i32>,
  5. }
  6. impl Race {
  7. // No receiver, a static method
  8. fn new(name: &str) -> Self {
  9. Self { name: String::from(name), laps: Vec::new() }
  10. }
  11. // Exclusive borrowed read-write access to self
  12. fn add_lap(&mut self, lap: i32) {
  13. self.laps.push(lap);
  14. }
  15. // Shared and read-only borrowed access to self
  16. fn print_laps(&self) {
  17. println!("Recorded {} laps for {}:", self.laps.len(), self.name);
  18. for (idx, lap) in self.laps.iter().enumerate() {
  19. println!("Lap {idx}: {lap} sec");
  20. }
  21. }
  22. // Exclusive ownership of self
  23. fn finish(self) {
  24. let total: i32 = self.laps.iter().sum();
  25. println!("Race {} is finished, total lap time: {}", self.name, total);
  26. }
  27. }
  28. fn main() {
  29. let mut race = Race::new("Monaco Grand Prix");
  30. race.add_lap(70);
  31. race.add_lap(68);
  32. race.print_laps();
  33. race.add_lap(71);
  34. race.print_laps();
  35. race.finish();
  36. // race.add_lap(42);
  37. }

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 from self by trying to run finish twice.
    • Beyond variants on self, there are also special wrapper types allowed to be receiver types, such as Box<Self>.