diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | src/main.rs | 74 |
4 files changed, 90 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..bf2e770 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "lesson2" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..df959c5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "lesson2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..38c9288 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,74 @@ +use std::iter::ExactSizeIterator; + +// Согласно принципам программирования, управляемого данными, +// мы инкапсулируем данные в простые классы (в Rust - структуры)-контейнеры. +// Все методы для работы с данными вынесены в отдельные структуры, которые +// могут быть использованы в другом коде и для других данных с минимальными +// изменениями. +// Таким образом, мы отделяем код от данных. + +// Универсальная структура для хранения итератора общего типа +// (использование именно итератора (с известным размером) требуется +// характеристикой ExactSizeIterator в определении структуры. +struct Contents<T: ExactSizeIterator> { + contents: T, +} + +// Структура данных почтового ящика +struct Mailbox<T: ExactSizeIterator> { + contents: Contents<T>, + unread: bool, +} + +// Структура простого ящика +struct Box<T: ExactSizeIterator> { + volume: u8, + objects: Contents<T>, +} + +// Проверяльщик содержимого контейнера. +// Структура реализует метод is_empty для проверки размера содержимого. +// Работает с нашей общей реализацией структуры-"контейнера" Contents +struct ContainerChecker {} +impl ContainerChecker { + fn is_empty<T: ExactSizeIterator>(data: &Contents<T>) -> bool { + return data.contents.len() == 0; + } +} + +// Проверяльщик почтового ящика. Работает с почтовыми ящиками. +struct MailChecker {} +impl MailChecker { + fn check_mail<T: ExactSizeIterator>(mbox: &Mailbox<T>) { + if mbox.unread { + println!("Есть непрочитанные сообщения!"); + } else { + println!("Непрочитанных писем нет."); + } + } +} + + +fn main() { + let box_contents = Contents {contents: [1, 2, 3, 4].iter()}; + let b = Box { volume: 16, objects: box_contents}; + + if ContainerChecker::is_empty(&b.objects) { + println!("Коробка пуста!"); + } else { + println!("В коробке что-то есть!"); + } + + let mail_contents = Contents {contents: ["Письмо", "Ещё письмо"].iter()}; + let m = Mailbox { contents: mail_contents, unread: true }; + + // тот же проверяльщик, что использовался для проверки ящика, можно + // использовать и для почтового ящика - без всяких наследований. + if ContainerChecker::is_empty(&m.contents) { + println!("Почтовый ящик пуст!"); + } else { + print!("В почтовом ящике есть письма; "); + + MailChecker::check_mail(&m); + } +} |