Часто буває корисно зібрати набір елементів докупи й працювати з такими групами як з єдиним цілим. У Rust таку групу називають структурою, а кожен елемент - одним із полів структури. Структура задає загальний набір доступних полів, а конкретний приклад структури називають екземпляром.
Крім того, для структур можна визначати методи, які мають доступ до полів. Саму структуру в такому разі називають self. Коли метод використовує &mut self, поля можна змінювати, тобто мутувати. Коли метод використовує &self, поля змінити не можна: вони незмінні. Контроль за змінністю допомагає перевірці позичань гарантувати, що цілі класи помилок конкурентності просто не трапляються в Rust.
У цій вправі ми будемо реалізовувати два види методів у структурі. Перші зазвичай називають гетерами: вони показують поля структури назовні, не дозволяючи нікому іншому змінити це значення. У Rust ці методи за домовленістю мають таку саму назву, як і поле, яке вони показують. Тобто якщо в нас є метод-гетер, що дістає поле структури з назвою name, то метод просто називатиметься name().
Ми також будемо реалізовувати методи іншого типу, які зазвичай називають сетерами. Вони змінюють значення поля. Сетери в Rust не дуже поширені: якщо поле можна вільно змінювати, частіше його просто роблять публічним. Але вони стають у пригоді, якщо оновлення поля має спричиняти побічні ефекти, або для контролю доступу: сетер, позначений як pub(crate), дозволяє іншим модулям у тому самому крейті оновлювати приватне поле, на яке не може впливати зовнішній світ.
Структури бувають трьох видів: структури з іменованими полями, кортежні структури та одиничні структури. У цій концептуальній вправі ми розглянемо перший варіант: структури з іменованими полями.
Структури визначають за допомогою ключового слова struct, після якого йде назва типу, який описує структура, з великої літери:
struct Item {}
Далі до тіла структури додають інші типи як поля структури, кожне зі своїм типом:
struct Item {
name: String,
weight: f32,
worth: u32,
}
І нарешті, методи можна визначити для структури всередині блоку impl:
impl Item {
// initializes and returns a new instance of our Item struct
fn new() -> Self {
todo!()
}
}
Тепер, коли ми коротко ознайомилися із синтаксисом структур, погляньмо на інструкції до цієї вправи!
Ми працюємо над реалізацією системи моніторингу здоровʼя. У межах цього нам потрібно відстежувати статистику здоровʼя користувачів.
Ми почнемо з кількох функцій-заглушок у блоці impl, а також із такого визначення структури:
pub struct User {
name: String,
age: u32,
weight: f32,
}
Наша мета - реалізувати методи-заглушки на struct User, визначеній у блоці impl.
Наприклад, метод new має повертати екземпляр структури User із заданими значеннями імені, віку і ваги.
let mut bob = User::new(String::from("Bob"), 32, 155.2);
// Returns: a User with name "Bob", age 32, and weight 155.2
Метод weight має повертати вагу екземпляра User.
bob.weight();
// Returns: 155.2
Метод set_age має встановлювати вік екземпляра User.
bob.set_age(33);
// Updates Bob's age to 33; happy birthday Bob!
Гарного кодування!