方法

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