2016-06-10 8 views
5

연습용으로 비트 벡터 라이브러리를 구현하려고하지만 제네릭 형식 매개 변수의 기본값을 정의 할 때 문제가 발생합니다. 기본 제네릭 형식 매개 변수를 유추 할 수 없습니다.

코드의 발췌 한 것입니다 내가 가진 :

extern crate num; 

use std::cmp::Eq; 
use std::ops::{BitAnd,BitOrAssign,Index,Shl}; 
use num::{One,Zero,Unsigned,NumCast}; 

pub trait BitStorage: Sized + 
    BitAnd<Self, Output = Self> + 
    BitOrAssign<Self> + 
    Shl<Self, Output = Self> + 
    Eq + Zero + One + Unsigned + NumCast + Copy {} 

impl<S> BitStorage for S where S: Sized + 
    BitAnd<S, Output = S> + 
    BitOrAssign<S> + 
    Shl<S, Output = S> + 
    Eq + Zero + One + Unsigned + NumCast + Copy {} 

pub struct BitVector<S: BitStorage = usize> { 
    data: Vec<S>, 
    capacity: usize 
} 

impl<S: BitStorage> BitVector<S> { 
    pub fn with_capacity(capacity: usize) -> BitVector<S> { 
     let len = (capacity/(std::mem::size_of::<S>() * 8)) + 1; 
     BitVector { data: vec![S::zero(); len], capacity: capacity } 
    } 

    //... 
} 

다음과 같이 나는 그것을 사용하려면 :

lib.rs:225:24: 225:48 error: unable to infer enough type information about _ ; type annotations or generic parameter binding required [E0282]
lib.rs:225 let vec_1000 = BitVector::with_capacity(1000);
^~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:225:24: 225:48 help: run rustc --explain E0282 to see a detailed explanation

: 나는 컴파일러 오류 그러나

let vec = BitVector::with_capacity(1024); 

코드에 좀 더 많은 컨텍스트를 제공하기 위해 현재 유효한 유형은 BitStorage입니다 (이에 국한되지 않음 *) u8, u16, u32, u64usize.

(*) 해당 유형의 모든 특성을 구현하는 경우 사용자 정의 u128 구현 (예제처럼)을 작성할 수 있다고 생각합니다.

be stable yet으로 보이지 않는 RFC 213이라는 문제를 찾은 후. 그러나 다른 한편으로는 HashMap 현재 안정적으로 기본값을 사용하고 있으므로 제대로 작동해야합니다.

답변

3

기본 유형 매개 변수에 대한 지원은 여전히 ​​제한되어 있지만 경우에 따라 사용할 수 있습니다. ,

// the type of vec is BitVector<usize>, so the type of 
// BitVector::with_capacity(1024) is correctly inferred 
let vec: BitVector = BitVector::with_capacity(1024); 

However on the other hand HashMap currently on stable is using default values, so it should be working, right?

HashMap 소스 코드를 보면 우리가 할 수있는 : 기본 형식 매개 변수와 struct 변수의 유형을 지정하는 데 사용되는 경우, 기본 유형 매개 변수는 변수의 유형을 정의하는 데 사용됩니다 newwith_capacityS 매개 변수의 경우 RandomState으로 구현되며 HashMap의 기본 유형 매개 변수에 의존하지 않습니다. 다른 모든 메소드는 S에 일반으로 구현되며 with_hasher과 같은 다른 "생성자"메소드를 포함합니다.

당신은 비슷한 쓸 수 있습니다 :

impl BitVector<usize> { 
    pub fn default_with_capacity(capacity: usize) -> BitVector<usize> { 
     // type is inferred 
     Self::with_capacity(capacity) 
    } 
} 

impl<S: BitStorage> BitVector<S> { 
    pub fn with_capacity(capacity: usize) -> BitVector<S> { 
     let len = (capacity/(std::mem::size_of::<S>() * 8)) + 1; 
     BitVector { 
      data: vec![S::zero(); len], 
      capacity: capacity, 
     } 
    } 

    // ... 
} 

// create with "default" BitStore 
let vec = BitVector::default_with_capacity(1024); 
// specify BitStore 
let vec = BitVector::<u32>::with_capacity(1024); 
관련 문제