Структуры и методы
Структуры объединяют именованные поля в один тип; методы добавляются через блок impl.
Структура (struct) — пользовательский тип, объединяющий несколько именованных полей в одно целое.
Объявление и создание
Структура описывает «вещь» с набором свойств. Сначала объявляют тип с полями, затем создают экземпляры.
struct User {
name: String,
age: u32,
active: bool,
}
fn main() {
let u = User {
name: String::from("Аня"),
age: 28,
active: true,
};
println!("{} ({}), активен: {}", u.name, u.age, u.active);
}Вывод:
Аня (28), активен: true
Чтобы менять поля экземпляра, всю переменную объявляют как mut — отдельные поля изменяемыми пометить нельзя, изменяемость относится ко всему значению.
Методы через impl
Поведение структуры описывают в блоке impl. Метод, который работает с конкретным экземпляром, первым параметром принимает &self — ссылку на сам объект (аналог this в других языках).
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// метод: читает поля через неизменяемую ссылку на self
fn area(&self) -> u32 {
self.width * self.height
}
// метод, который меняет self, берёт &mut self
fn scale(&mut self, factor: u32) {
self.width *= factor;
self.height *= factor;
}
}
fn main() {
let mut r = Rectangle { width: 3, height: 4 };
println!("площадь = {}", r.area());
r.scale(2);
println!("после увеличения = {}", r.area());
}Вывод:
площадь = 12 после увеличения = 48
Заметьте связь с владением: &self — заимствование для чтения, &mut self — для изменения. Те же правила, что для обычных ссылок.
Ассоциированные функции и конструкторы
Функция в impl без self — ассоциированная функция, она привязана к типу, а не к экземпляру. Их вызывают через ::. Чаще всего так делают конструкторы по имени new.
struct Point {
x: i32,
y: i32,
}
impl Point {
fn new(x: i32, y: i32) -> Point {
Point { x, y } // короткая запись, когда имя поля совпадает с переменной
}
fn origin() -> Point {
Point::new(0, 0)
}
}
fn main() {
let p = Point::new(2, 3); // вызов через ::
let o = Point::origin();
println!("({}, {}) и ({}, {})", p.x, p.y, o.x, o.y);
}Вывод:
(2, 3) и (0, 0)
Когда имя поля совпадает с именем переменной (x, y), можно писать просто Point { x, y } вместо Point { x: x, y: y } — это называется сокращённой инициализацией полей.
Кортежные структуры
Иногда имена полей не нужны — тогда удобна кортежная структура: те же поля, но доступ по индексу. Полезно для простых обёрток.
struct Color(u8, u8, u8); // R, G, B
fn main() {
let red = Color(255, 0, 0);
println!("R={} G={} B={}", red.0, red.1, red.2);
}Вывод:
R=255 G=0 B=0
Итог
- Структура объединяет именованные поля; методы добавляют в блоке
impl. - Метод экземпляра берёт
&self(чтение) или&mut self(изменение) — это те же ссылки. - Функции без
self— ассоциированные, вызываются через::; так делают конструкторыnew.