2014-02-10 58 views
3

我試圖從頭開始在Rust中實現一個玩具hashmap,並在實際初始化我需要的桶時遇到阻礙。我已經使用了像u8這樣的其他基元的桶陣列(在下面的代碼片段中給出了註釋)。在Rust hashmap中分配/實例化字符串/向量的向量?

我無法弄清楚的是如何告訴編譯器爲我分配一個可變的向量,其中包含其他向量 - 在這種情況下,~str。此代碼編譯,但在運行時失敗,出現index out of bounds錯誤。

static DEFAULT_NUMBER_OF_BUCKETS: uint = 64; 
static DEFAULT_VALUE_LENGTH: uint = 32; //unused 

struct NaiveHashMap { 
    hashmap_size: uint, //unused. 
    string_capacity: uint, //unused. 
    //contents: ~[ u8 ] 
    contents: ~[ ~str ] 
} 

impl NaiveHashMap { 

    fn new(hash_size: uint, string_size: uint) -> NaiveHashMap { 
     NaiveHashMap { 
      hashmap_size: hash_size, //unused 
      string_capacity: string_size, //unused 
      //contents: ~[ 0, ..DEFAULT_NUMBER_OF_BUCKETS ] 
      contents: std::vec::with_capacity::<~str>(DEFAULT_NUMBER_OF_BUCKETS) 
     } 
    } 

    fn get_hash(&self, key: &str) -> u32 { 
     let hash: u32 = jenkins_hash(key); 
     hash % self.hashmap_size.to_u32().unwrap() 
    } 

    //fn add(&mut self, key: &str, value: u8) { 
    fn add(&mut self, key: &str, value: ~str) { 
     let bucket = self.get_hash(key); 
     self.contents[bucket] = value; 
    } 

    //fn get(self, key: &str) -> u8 { 
    fn get(&self, key: &str) -> ~str { 
     let bucket = self.get_hash(key); 
     self.contents[bucket].clone() 
    } 

} 

短調用不安全from_buf分配或只是copypasting性病的Hashmap LIB的,我不能確定如何進行。

我認識到在班級周圍傳遞<T>是更好的做法,所以它會很靈活,但是首先要想清楚這點。

編輯:修改get()以避免捕獲整個結構。

回答

6

據我所知,你想構造一個給定長度的向量來通過索引寫入東西。

除非您爲矢量的每個元素指定默認值,否則您無法安全地在Rust中執行此操作。它曾與~[u8],因爲你沒有指定默認值(零),因爲u8是隱式可複製:

[0, ..DEFAULT_NUMBER_OF_BUCKETS] 

但是,你所期待的默認值~str?它是一個指針,Rust中的指針不能等於null,這對指針來說是最自然的默認值。 ~str的下一個最自然的值,我認爲是~"",也就是一個空字符串。您可以使用它來創建N字符串矢量:

vec::from_elem(N, ~"") 

這將創建一個空的盒裝字符串矢量。但它也意味着N分配,而不是你不應該考慮的事情。

但是,您不能使用任意類型T來執行此操作,因爲通常任意類型T沒有任何默認值。此外,任意T也可以不是Clone,這是from_elem()所要求的。但是您可以從T創建另一個類型,該類型具有默認值。您可以使用Option此:

contents: ~[Option<T>] 

爲了克服非cloneability,您可以使用from_fn()功能與閉合:

contents: vec::from_fn(N, |_| None) 

順便說一句,它失敗的原因與「索引越界」錯誤因爲你正在使用with_capacity()函數。此功能可創建零長度爲的矢量,其長度爲,但具有指定的的容量。您可以在矢量上使用push()方法將元素附加到該元素的末尾,並且在達到其容量之前不會重新分配元素,但無法訪問添加元素「外部」的元素。