Методи

Rust дозволяє пов’язувати функції з новими типами. Ви робите це за допомогою блоку impl:

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

impl Race {
    // Немає отримувача, статичний метод
    fn new(name: &str) -> Self {
        Self { name: String::from(name), laps: Vec::new() }
    }

    // Ексклюзивний запозичений доступ на читання та запис до себе
    fn add_lap(&mut self, lap: i32) {
        self.laps.push(lap);
    }

    // Спільний та запозичений доступ тільки на читання до себе
    fn print_laps(&self) {
        println!("Записано {} кіл для {}:", self.laps.len(), self.name);
        for (idx, lap) in self.laps.iter().enumerate() {
            println!("Коло {idx}: {lap} sec");
        }
    }

    // Виключне володіння собою
    fn finish(self) {
        let total: i32 = self.laps.iter().sum();
        println!("Гонка {} завершена, загальний час проходження кола: {}", self.name, total);
    }
}

fn main() {
    let mut race = Race::new("Гран-прі Монако");
    race.add_lap(70);
    race.add_lap(68);
    race.print_laps();
    race.add_lap(71);
    race.print_laps();
    race.finish();
    // race.add_lap(42);
}

Аргументи self визначають "отримувача" - об'єкт, на який діє метод. Існує декілька типових отримувачів для методу:

  • &self: запозичує об’єкт у викликувача за допомогою спільного та незмінного посилання. Після цього об’єкт можна використовувати знову.
  • &mut self: запозичує об’єкт у викликувача, використовуючи унікальне та мутабельне посилання. Після цього об’єкт можна використовувати знову.
  • self: приймає право власності на об'єкт і переміщує його від викликувача. Метод стає власником об'єкта. Об’єкт буде видалено (звільнено), коли метод завершиться, якщо володіння їм не передано явно. Повне володіння не означає автоматичної мутабельності.
  • mut self: те саме, що й вище, але метод може змінювати об’єкт.
  • Немає отримувача: це стає статичним методом у структурі. Зазвичай використовується для створення конструкторів, які за домовленістю називаються new.
This slide should take about 8 minutes.

Ключові моменти:

  • Може бути корисно представити методи, порівнюючи їх із функціями.
    • Методи викликаються для екземпляра типу (такі як структура або перелік), перший параметр представляє екземпляр як self.
    • Розробники можуть використовувати методи, щоб скористатися перевагами синтаксису отримувача методів і допомогти їм бути більш організованими. Використовуючи методи, ми можемо зберігати весь код реалізації в одному передбачуваному місці.
  • Зверніть увагу на використання ключового слова self, отримувача методу.
    • Покажіть, що це скорочений термін для self: Self і, можливо, покажіть, як можна також використовувати назву структури.
    • Поясніть, що Self — це псевдонім типу для типу, до якого входить блок impl, і його можна використовувати деінде в блоці.
    • Зауважте, що self використовується, як і інші структури, і крапкова нотація може використовуватися для посилання на окремі поля.
    • Це може бути гарний час, щоб продемонструвати, чим &self відрізняється від self, спробувавши запустити finish двічі.
    • Окрім варіантів self, існують також спеціальні типи обгорток, які можуть бути типами отримувачів, наприклад Box<Self>.