範例

#[derive(Debug)]
struct Race {
    name: String,
    laps: Vec<i32>,
}

impl Race {
    fn new(name: &str) -> Race {  // No receiver, a static method
        Race { name: String::from(name), laps: Vec::new() }
    }

    fn add_lap(&mut self, lap: i32) {  // Exclusive borrowed read-write access to self
        self.laps.push(lap);
    }

    fn print_laps(&self) {  // Shared and read-only borrowed access to self
        println!("Recorded {} laps for {}:", self.laps.len(), self.name);
        for (idx, lap) in self.laps.iter().enumerate() {
            println!("Lap {idx}: {lap} sec");
        }
    }

    fn finish(self) {  // Exclusive ownership of self
        let total = self.laps.iter().sum::<i32>();
        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);
}

重點:

  • 這裡的四個方法都使用不同的方法接收器。
    • 您可以指出這會如何變更函式能對變數值執行的動作,以及可否/如何在 main 中再次使用該函式。
    • 您可以演示嘗試呼叫 finish 兩次時會出現什麼錯誤。
  • 請注意,雖然方法接收器不同,但主體中非靜態函式的呼叫方式相同。Rust 會在呼叫方法時啟用自動參照和取消參照功能,並自動加入 &*muts,讓該物件與方法簽章相符。
  • 您或許可以指出 print_laps 使用了不斷疊代的向量。我們會在下午詳細介紹向量。