Параметр Self
Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 2 из 61.
Когда методу требуется получить доступ к данным, хранящимся в экземпляре структуры, он использует параметр &self. Этот специальный параметр всегда является первым аргументом метода и представляет ссылку на экземпляр, для которого вызывается метод.
Символ & означает, что мы заимствуем instance, а не получаем владение им. Это позволяет методу читать поля struct, не поглощая instance:
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn is_square(&self) -> bool {
self.width == self.height
}
}
Внутри тела метода self предоставляет доступ ко всем полям структуры с использованием точечной нотации. Метод area считывает и width, и height, чтобы вычислить и вернуть результат.
Поскольку &self только заимствует instance, вы можете без проблем вызывать несколько методов у одной и той же структуры:
fn main() {
let rect = Rectangle { width: 10, height: 5 };
println!("Area: {}", rect.area()); // 50
println!("Square? {}", rect.is_square()); // false
}
Методы, использующие &self, предназначены только для чтения. Они могут изучать данные структуры, но не могут изменять их. На следующем уроке вы узнаете, как создавать методы, которые могут изменять instance.
Задание
ЛегкоСоздай структуру Circle с единственным полем: radius (f64).
Добавь блок реализации для Circle с двумя методами, которые используют &self:
circumference: возвращает длину окружности какf64(формула:2.0 * 3.14159 * radius)diameter: возвращает диаметр какf64(формула:2.0 * radius)
Ты получишь одни входные данные:
- Радиус круга (f64)
Создай экземпляр Circle с указанным радиусом, затем выведи длину окружности и диаметр в отдельных строках.
Ожидаемый формат вывода:
{circumference}
{diameter}Попробуйте сами
use std::io;
// TODO: Определите структуру Circle здесь
// TODO: Добавьте блок реализации для Circle с методами circumference и diameter
fn main() {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read line");
let radius: f64 = input.trim().parse().expect("Invalid number");
// TODO: Создайте экземпляр Circle и выведите circumference и diameter
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media PlayerПотренируйтесь самостоятельно: Онлайн-компилятор Rust