2017-10-15 70 views
-5

我有結構的載體。我想爲每個元素添加一個附加字段。什麼是最好的方式來做到這一點?添加新的關鍵向量的每個元素在鏽病

像這樣:

// Pseudo code 

let items = vec![elem1, elem2, elem3, elem4]; 
for x in items { 
    // Something like this 
    x["some_additional_key"] = get_data(x); 
} 

// 
// Now I have items[i].some_additional_key in each element 
+6

你[問完全相同的問題上/ R /rust](https://www.reddit.com/r/rust/comments/76grm4/add_a_key_to_each_element_of_a_vector/)並在那裏得到了答案。正如Reddit上的人已經解釋過的:你想要的是Rust中不可能的。結構在編譯時有固定的佈局,不能在運行時修改。要有一個任意的鍵值存儲,可以使用'HashMap'或類似的東西。 –

+1

但是,而不是使用'HashMap'你應該做的這些事情之一:切換到像JavaScript語言,實際上可以做你想做的*或*試着想想你以另一種方式的程序。將你的一種編程語言的思維方式直接翻譯成另一種編程語言是行不通的,特別是不適用於Rust。如果你重新思考你的問題,你可能會想出一個更好的解決方案。 –

回答

4

鏽病是statically-typed language;您可能熟悉其他類似的語言,如C++,Java或Swift。在這些語言中,編譯程序時,結構的成員,類型和佈局是固定的。

正因爲如此,有沒有辦法在運行時添加一個新的結構場 - 沒有「如果」,「阿富汗國家發展戰略」,或「但是」 - 你不能做到這一點。

相反,你要一些其他的方式模型,動態性:

  1. 使用類型,允許任意擴展。 HashMapBTreeMap(和許多其他類似的類型)允許您擁有任意數量的鍵值對。引擎蓋下,這基本上是許多動態語言是如何工作的 - 字符串的映射爲任意值:

    use std::collections::HashMap; 
    
    #[derive(Debug, Default)] 
    struct Element(HashMap<String, u8>); 
    
    fn get_data(_: &Element) -> u8 { 
        42 
    } 
    
    fn main() { 
        let mut items = vec![ 
         Element::default(), 
         Element::default(), 
         Element::default(), 
         Element::default(), 
        ]; 
    
        for x in &mut items { 
         let value = get_data(x); 
         x.0 
          .entry("some_additional_key".to_string()) 
          .or_insert(value); 
        } 
    } 
    
  2. 使用一種類型,允許特定的展開。 Option允許值設定爲存在或不存在:

    #[derive(Debug, Default)] 
    struct Element { 
        some_additional_key: Option<u8>, 
    } 
    
    fn get_data(_: &Element) -> u8 { 
        42 
    } 
    
    fn main() { 
        let mut items = vec![ 
         Element::default(), 
         Element::default(), 
         Element::default(), 
         Element::default(), 
        ]; 
    
        for x in &mut items { 
         let value = get_data(x); 
         x.some_additional_key = Some(value); 
        } 
    } 
    
  3. 使用組合物。創建一個新的類型,它包裝現有的類型:

    #[derive(Debug, Default)] 
    struct Element; 
    
    #[derive(Debug)] 
    struct EnhancedElement { 
        element: Element, 
        some_additional_key: u8, 
    } 
    
    fn get_data(_: &Element) -> u8 { 
        42 
    } 
    
    fn main() { 
        let items = vec![ 
         Element::default(), 
         Element::default(), 
         Element::default(), 
         Element::default(), 
        ]; 
    
        let enhanced: Vec<_> = items 
         .into_iter() 
         .map(|element| { 
          let some_additional_key = get_data(&element); 
          EnhancedElement { 
           element, 
           some_additional_key, 
          } 
         }) 
         .collect(); 
    } 
    

參見:已經