我正在将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
创建一个由全零组成的位值。我得到的错误如下:
最佳答案
简单来说,这里的特定错误意味着Output
和BitAnd
的S
的usize
不实现PartialEq
。一种解决方法是添加一个约束,使S
的BitAnd<usize>
的Output
为S
:
BitAnd<usize, Output = S>
此后,您将遇到另一个错误,因为您将BitAnd的值与
0
而不是S
类型的值进行比较。要解决此问题,您可以定义自己的Zero
特征并使用它,或者使用Rust不稳定的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() {
}
关于generics - 对位向量使用泛型时,不能应用二进制运算!=,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37613850/