8

我正在实现一个 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, , 之一u32u64usize确保将其设置为0in创建一个由全零组成的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 << remaining)) != 0
^~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:27:10:27:50 帮助:运行rustc --explain E0369查看详细说明
lib.rs:27:10: 27:50 注意:lib.rs: 27 (self.data[ std::cmp::PartialEqdata_index <S as std::ops::BitAnd<usize>>::Output
] & (1 << remaining)) != 0 ^~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
错误:由于先前的错误而中止
错误:无法编译bit-vector.

4

1 回答 1

5

简单来说,这里的这个特殊错误意味着Outputof BitAndingSusize没有实现PartialEq. S一种解决方法是添加s BitAnd<usize>isOutput的约束S

BitAnd<usize, Output = S>

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

您还必须确保S: Copy这样做BitAnd不会消耗该值(或S: Clone在调用之前添加并显式克隆BitAnd::bitand)。

最后你会遇到一个错误,当你返回index一个. 您可以使用bit-vec使用的技巧来定义 2 个静态:&boolbool

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() {
}
于 2016-06-03T13:11:20.167 回答