2016-06-03 6 views
7

연습 문제로 비트 벡터 클래스를 구현하는 중일 뿐이지 만 다음 주 코드로 문제가 생기는 일주일도 안되는 녹을 알고 있습니다. :비트 벡터에 제네릭을 사용할 때 이진 연산! = 적용 할 수 없음

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 
    } 
} 

아이디어 Swith_capacity0로 설정하면 모두 0으로 구성 S 대한 비트 값을 생성하도록, 예 u8, u16, u32, u64 들면 하나 usize 될 수 있다는 것이다. 여기

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 .

+2

하지만,'인덱스 :: 당신은 즉시 그것을 계산할 수 있도록'& Output'을 반환 index'. .. –

답변

5

이 특정 오류가 간단한 용어, BitAndOutputPartialEq를 구현하지 않습니다 Susize를 보내고 있음을 의미합니다 :

내가 오류는이 다음이다. 당신이 0 및하지로에 BITAND의 값을 비교하고 있기 때문에 다른 오류로 실행하는 것,이 후

BitAnd<usize, Output = S> 

: 한 수정 SBitAnd<usize>OutputS하는 제약 조건을 추가하는 것입니다 형식은 S입니다. 자신의 Zero 특성을 정의하고이를 사용하거나 녹의 불안정한 std::num::Zero을 사용하여 S::zero()과 비교할 수 있다고 수정하십시오.

또한 BitAnd을 수행하면 값을 소비 (또는 S: Clone를 추가하고 명시 적으로 BitAnd::bitand를 호출하기 전에 복제)하지 않도록 S: Copy을해야합니다.

마지막으로 이 bool을 반환하는 동안 &bool을 반환해야한다는 오류가 발생합니다. index에서

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

반환 &TRUE 또는 &FALSE : 당신은 트릭 bit-vec 2 정적을 정의하는 데 사용 할 수 있습니다.

(박)에 최종 작업 코드 : 나는 당신의 퍼레이드에 비하지 않으

#![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() { 
} 
+0

고마워! 이것은 지금까지 컴파일러 오류에서 즉시 명확하지 않았습니다. '& TRUE & FALSE' "해킹"이 의도되었거나 현재 언어 단점이 있습니까? 마지막으로'S : Sized + BitAnd + Not + Eq + Copy + Zero'를 복사하는 것을 피하는 관용적 인 방법이 있습니까? – skiwi

+0

나는 그것이 순간에 단점이라고 생각하지만 미래에 변경 될지 확실하지 않다. Rust 하위 태그에 대한 [많은 토론] (https://www.google.com/search?q=site%3Areddit.com%2Fr%2Frust+index+return+value)이 있습니다 (예 : 자세한 설명을 읽으려면 [this] (https://www.reddit.com/r/rust/comments/2umad5/the_output_of_the_index_trait_should_be_a_value/)를 클릭하십시오. – Dogbert

+0

예, 특성 상속을 사용할 수 있습니다. http://stackoverflow.com/questions/26983355/is-there-a-way-to-combine-multiple-traits-in-order-to-define-a-new-trait를 참조하십시오. 데모 : https://play.rust-lang.org/?gist=efa13f778d31cdd6f90e79962fd379d2&version=nightly&backtrace=0 – Dogbert