Как продлить использование?

Я новичок в Расте. Следующий код — это моя попытка создать расширение использования, которое позволяет:

  • установка длины в битах
  • печать в битах с ведущими нулями в зависимости от длины
  • самое главное, переход к следующей лексикографической перестановке битов. (например, 0101 -> 0110)

Структура ниже делает все это, но в остальном она не ведет себя как использование. Возможно, я все делаю неправильно, и структура не подходит для этого. В качестве примера того, что это не работает:

let mut permutable_usize = PermutableUsize::new(0b00010011, 8);
permutable_usize += 1;

Вышеупомянутое генерирует ошибку и говорит, что я должен реализовать AddAssign<_>.

Я уверен, что есть «правильный способ» сделать это, который позволяет избежать повторной реализации всех методов использования. Как мне действовать?

Вот что у меня есть сейчас:

struct PermutableUsize {
    value: usize,
    num_bits: usize,
}

impl PermutableUsize {
    fn new(value: usize, num_bits: usize) -> Self {
        Self {
            value,
            num_bits,
        }
    }

    // Method to compute the next lexicographic permutation of bits
    // The logic comes from bit-twiddling hacks at https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation 
    fn next_permutation(&mut self) {
        let t = self.value | (self.value - 1);
        let ctz_v = self.value.trailing_zeros();
        self.value = (t + 1) | (((!t & (!t).wrapping_neg()) - 1) >> (ctz_v + 1));
    }
}

use std::fmt;

impl fmt::Binary for PermutableUsize {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:0width$b}", self.value, width = self.num_bits)
    }
}

fn main() {
    let mut permutable_usize = PermutableUsize::new(0b00010011, 8); // example with 8 bits
    println!("Initial value: {:08b}", permutable_usize); 

    permutable_usize.next_permutation();
    println!("Next permutation: {:08b}", permutable_usize); 
}

Правильный путь — реализовать все методы, хотя существуют ящики , которые могут в этом помочь (а также предлагаемый RFC).

Chayim Friedman 10.07.2024 23:28

@ChayimFriedman Это полезный и окончательный ответ. Если вы хотите перенести это из комментариев в ответ, я поддержу и приму это.

Dave 11.07.2024 00:50
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
2
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Правильный способ — реализовать все методы, но вам не обязательно делать это вручную: есть крейты, которые могут в этом помочь, например Derivate_more . Также существует предлагаемый RFC, который поможет в этом. Общий шаблон называется «делегирование».

Если вы хотите, чтобы все методы usize были доступны, вы можете реализовать Deref. Однако сообщество Rust разделилось во мнениях относительно того, хорошая ли это идея. Кроме того, это не помогает с чертами (тут помогают ящики, о которых я упомянул).

Другие вопросы по теме