C
Code for Bro
@codeforbro9 подп.
31просмотров
13 августа 2024 г.
Score: 34
Реализацию интерфейса для перечисления и зацикленного перечисления на Rust: // Объявляем модуль cursor, что бы скрыть лишние подробности реализации. mod cursor { // Характеристика Bounded вводить 2 функции, которые позволяют понять какие // максимальные и минимальные значения могут быть у типа. pub trait Bounded where Self: Sized, { fn max_value() -> Self; fn min_value() -> Self; } // Характеристика Enumeration, которая вводить функции получения следующего // и предыдущего значений. pub trait Enumeration { fn succ(&self) -> Self; fn prev(&self) -> Self; } // Характеристика LoopedEnumeration зависит от Bounded и Enumeration, что // позволяет использовать их методы, т.е. для того, что бы реализовать эту // характеристику тип уже должен реализовать зависимые характеристики; // вводит те же функции, что и Enumeration, но его поведение меняется и // при инкременте при достижении максимального значения будет подставлено // минимальное и наоборот для декремента; как видно, используются функции // характеристик, по этому можно подготовить реализацию по умолчанию, // которая будет автоматически доступной для всех типов реализовавших // Bounded и Enumeration. pub trait LoopedEnumeration: Bounded + Enumeration where Self: PartialEq, { fn succ(&self) -> Self { if self == <Self as Bounded>::max_value() { <Self as Bounded>::min_value() } else { <Self as Enumeration>::succ(self) } } fn prev(&self) -> Self { if self == <Self as Bounded>::min_value() { <Self as Bounded>::max_value() } else { <Self as Enumeration>::prev(self) } } } // константа, которая вводить ограничение. const LIMIT: usize = 4; // Объявляем наш Cursor и автоматически реализуем для него: // - Debug - что бы была возможность распечатать дебажный принт; // - Default - что бы было просто создавать новые экземпляры; // - PartialEq - что бы сравнивать на равенство. // внутри корсора будет число типа usize, которое нам надо увеличивать // и уменьшать. #[derive(Debug, Default, PartialEq)] pub struct Cursor(usize); // Описываем для Cursor какие у него максимальные и минимальные значения. impl Bounded for Cursor { fn max_value() -> Self { Self(LIMIT - 1) } fn min_value() -> Self { Self(0) } } // Описываем для Cursor как получить следующее и предыдущие значения. impl Enumeration for Cursor { fn succ(&self) -> Self { Self(self.0 + 1) } fn prev(&self) -> Self { Self(self.0 - 1) } } // Бесплатная релаизация зацикленного перечисления. impl LoopedEnumeration for Cursor {} } fn main() { // Импортируем только Cursor и LoopedEnumeration, что бы избежать вызова // метода характеристики (см. реализацию по умолчанию для LoopedEnumeration) use cursor::{Cursor, LoopedEnumeration}; // Получаем дефолтное значение Cursor, спасибо реализации Default. let mut cursor = Cursor::default(); // Вот тут пригождается реализацию Debug. println!("On start: {cursor:?}"); for id in 0..6 { // Получаем следующее значение курсора и выводим на экран. cursor = cursor.succ(); println!("On {id}: {cursor:?}"); } for id in 0..6 { // Получаем предыдущее значение курсора и выводим на экран. cursor = cursor.prev(); println!("On {id}: {cursor:?}"); } } /* Результаты: On start: Cursor(0) On 0: Cursor(1) On 1: Cursor(2) On 2: Cursor(3) On 3: Cursor(0) On 4: Cursor(1) On 5: Cursor(2) On 0: Cursor(1) On 1: Cursor(0) On 2: Cursor(3) On 3: Cursor(2) On 4: Cursor(1) On 5: Cursor(0)
31
просмотров
4000
символов
Нет
эмодзи
Нет
медиа

Другие посты @codeforbro

Все посты канала →