Двоичная операция!= Не может быть применена при использовании обобщенных значений для битового вектора
Я нахожусь в процессе реализации класса Bit Vector в качестве упражнения, однако, зная Rust менее недели, я столкнулся с проблемой следующего кода:
use std::cmp::Eq;
use std::ops::BitAnd;
use std::ops::Index;
use std::ops::Not;
struct BitVector<S = usize>
where S: Sized + BitAnd<usize> + Not + Eq {
data: Vec<S>,
capacity: usize
}
impl<S> BitVector<S>
where S: Sized + BitAnd<usize> + Not + Eq {
fn with_capacity(capacity: usize) -> BitVector {
let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
BitVector { data: vec![0; len], capacity: capacity }
}
}
impl<S> Index<usize> for BitVector<S>
where S: Sized + BitAnd<usize> + Not + Eq {
type Output = bool;
fn index(&self, index: usize) -> &bool {
let data_index = index / (std::mem::size_of::<S>() * 8);
let remainder = index % (std::mem::size_of::<S>() * 8);
(self.data[data_index] & (1 << remainder)) != 0
}
}
Идея в том, что S
может быть одним из например u8
, u16
, u32
, u64
а также usize
чтобы установить его на 0
в with_capacity
создает битовое значение для S
это состоит из всех нулей.
Я получаю следующую ошибку:
lib.rs:27:10: 27:50 ошибка: бинарная операция
!=
нельзя применять к типу<S as std::ops::BitAnd<usize>>::Output
[E0369]
lib.rs:27 (self.data[data_index] & (1 << остаток))! = 0
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:27:10: 27:50 help: runrustc --explain E0369
чтобы увидеть подробное объяснение
lib.rs:27:10: 27:50 примечание: реализацияstd::cmp::PartialEq
может отсутствовать для<S as std::ops::BitAnd<usize>>::Output
lib.rs:27 (self.data [data_index] & (1<< Остаток))!= 0 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ошибка: прерывание из-за предыдущей ошибки
ошибка: не удалось скомпилироватьbit-vector
,
1 ответ
Эта конкретная ошибка здесь, в простых терминах, означает, что Output
из BitAnd
ИНГ S
а также usize
не реализует PartialEq
, Одним из исправлений было бы добавить ограничение, которое S
"s BitAnd<usize>
s Output
является S
:
BitAnd<usize, Output = S>
После этого вы столкнетесь с другой ошибкой, потому что вы сравниваете значение BitAnd с 0
а не к значению типа S
, Чтобы исправить это, вы можете определить свой собственный Zero
черт и использовать это или использовать нестабильный Руст std::num::Zero
и сравнить с S::zero()
,
Вам также придется сделать S: Copy
так что делать BitAnd
не потребляет значение (или добавить S: Clone
и явно клонировать перед вызовом BitAnd::bitand
).
Наконец вы столкнетесь с ошибкой, что ваш index
должен вернуть &bool
пока вы возвращаете bool
, Вы можете использовать хитрость bit-vec, чтобы определить 2 статики:
static TRUE: bool = true;
static FALSE: bool = false;
и вернуться &TRUE
или же &FALSE
от index
,
Окончательный рабочий (по Ночному) код:
#![feature(zero_one)]
use std::cmp::Eq;
use std::num::Zero;
use std::ops::BitAnd;
use std::ops::Index;
use std::ops::Not;
struct BitVector<S = usize>
where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
data: Vec<S>,
capacity: usize,
}
impl<S> BitVector<S>
where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
fn with_capacity(capacity: usize) -> BitVector {
let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
BitVector {
data: vec![0; len],
capacity: capacity,
}
}
}
static TRUE: bool = true;
static FALSE: bool = false;
impl<S> Index<usize> for BitVector<S>
where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
type Output = bool;
fn index(&self, index: usize) -> &bool {
let data_index = index / (std::mem::size_of::<S>() * 8);
let remainder = index % (std::mem::size_of::<S>() * 8);
if (self.data[data_index] & (1 << remainder)) != S::zero() {
&TRUE
} else {
&FALSE
}
}
}
fn main() {
}