Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Методы

Rust позволяет связывать функции с вашими новыми типами. Это делается через блок impl:

// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

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

impl CarRace {
    // Без получателя, статический метод
    fn new(name: &str) -> Self {
        Self { name: String::from(name), laps: Vec::new() }
    }

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

    // Разделяемый заимствованный доступ только на чтение к 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");
        }
    }

    // Эксклюзивное владение 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 = CarRace::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);
}

Аргументы self задают «получатель» (receiver) — объект, над которым работает метод. Для методов есть несколько распространённых видов получателей:

  • &self: заимствует объект у вызывающего кода через разделяемую неизменяемую ссылку. Объект можно использовать снова после этого.
  • &mut self: заимствует объект у вызывающего кода через уникальную изменяемую ссылку. Объект можно использовать снова после этого.
  • self: забирает владение объектом и перемещает его из вызывающего кода. Метод становится владельцем объекта. Объект будет освобождён (удалён из памяти) при возврате из метода, если только его владение явно не передано дальше. Полное владение автоматически не означает изменяемость.
  • mut self: то же, что и выше, но метод может изменять объект.
  • Без получателя: это становится статическим методом структуры. Обычно так создают конструкторы, которые по соглашению называются new.
This slide should take about 8 minutes.

Ключевые моменты:

  • Может помочь введение методов через сравнение с функциями.
    • Методы вызываются для экземпляра типа (например, структуры или перечисления); первый параметр представляет экземпляр как self.
    • Разработчики могут использовать методы, чтобы воспользоваться синтаксисом получателя метода и лучше организовать код. Используя методы, мы держим весь код реализации в одном предсказуемом месте.
    • Обратите внимание, что методы также можно вызывать как ассоциированные функции, явно передавая получатель, например CarRace::add_lap(&mut race, 20).
  • Укажите на использование ключевого слова self — получателя метода.
    • Покажите, что это сокращение для self: Self, и, возможно, покажите, как можно использовать и имя структуры.
    • Объясните, что Self — псевдоним типа, для которого написан блок impl, и его можно использовать в других местах этого блока.
    • Покажите, что self используется как и другие структуры, и что для отдельных полей можно использовать точечную нотацию.
    • Это хороший момент, чтобы показать, чем &self отличается от self, попробовав вызвать finish дважды.
    • Помимо вариантов self, получателями могут быть и специальные типы-обёртки, например Box<Self>.