对位向量使用泛型时,不能应用二元运算 !=

Binary operation != cannot be applied when using generics for a bit vector

我正在实施位向量 class 作为练习,但是我只了解 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 可以是 u8u16u32u64usize 之一确保在 with_capacity 中将其设置为 0 会为 S 创建一个由全零组成的位值。

我得到的错误如下:

lib.rs:27:10: 27:50 error: binary operation != cannot be applied to type <S as std::ops::BitAnd<usize>>::Output [E0369]
lib.rs:27 (self.data[data_index] & (1 << remainder)) != 0
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:27:10: 27:50 help: run rustc --explain E0369 to see a detailed explanation
lib.rs:27:10: 27:50 note: an implementation of std::cmp::PartialEq might be missing for <S as std::ops::BitAnd<usize>>::Output
lib.rs:27 (self.data[data_index] & (1 << remainder)) != 0 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
error: Could not compile bit-vector.

这里的这个特殊错误,简单来说,意味着 BitAnding SusizeOutput 没有实现 PartialEq。一种解决方法是添加一个约束条件,即 SBitAnd<usize>s OutputS:

BitAnd<usize, Output = S>

在此之后,您将 运行 陷入另一个错误,因为您将 Bi​​tAnd 的值与 0 进行比较,而不是 S 类型的值。要解决这个问题,您可以定义自己的 Zero 特征并使用它,或者使用 Rust 的不稳定 std::num::Zero 并与 S::zero().

进行比较

您还必须制作 S: Copy 以便执行 BitAnd 不会消耗值(或添加 S: Clone 并在调用 [=30= 之前显式克隆]).

最后你会 运行 出错,你的 index 必须 return 一个 &bool 而你 return 一个 [=33] =].您可以使用 bit-vec 用来定义 2 个静态变量的技巧:

static TRUE: bool = true;
static FALSE: bool = false;

和 return &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() {
}