我正在将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可以是u8u16u32u64usize之一,以确保将其设置为0中的with_capacity会为S创建一个由全零组成的位值。

我得到的错误如下:

最佳答案

简单来说,这里的特定错误意味着OutputBitAndSusize不实现PartialEq。一种解决方法是添加一个约束,使SBitAnd<usize>OutputS:

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返回&FALSEindex

最终工作(每晚)代码:
#![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/

10-10 13:36