2015-10-21 8 views
1

假設下面的結構如何存儲遞歸REF一個struct內

struct Item<'a> { 
    items: Vec<&'a Item<'a>> 
} 

假設下面的變量包含許多Item對象空items領域。

let mut items: Vec<Item<'a>> = get_items(); 

假設我要添加到每個Item引用的items領域的所有其他Item對象在items矢量任務。

我目前的實現是

struct Item<'a> { 
    items: Vec<&'a Item<'a>>, 
} 

impl<'a> Item<'a> { 
    fn new() -> Item<'a> { 
     Item { items: vec![] } 
    } 
} 

fn main() { 
    let mut items = vec![Item::new(), Item::new()]; 
    while let Some(item) = items.pop() { 
     for another_item in &mut items { 
      item.items.push(another_item); 
     } 
     items.push(item); 
    } 
}` 

它失敗,因爲我做item.items.push(another_item);

+0

錯誤結束。我犯了一個錯誤 –

回答

0

你正在嘗試做的是不健全的。不知道你的用例,你的問題沒有一個好的解決方案。

您有幾個與可變性有關的錯誤。有了這些固定的,你的代碼就變成了:

struct Item<'a> { 
    items: Vec<&'a Item<'a>>, 
} 

impl<'a> Item<'a> { 
    fn new() -> Item<'a> { 
     Item { items: vec![] } 
    } 
} 

fn main() { 
    let mut items = vec![Item::new(), Item::new()]; 
    while let Some(mut item) = items.pop() { 
     for another_item in items { 
      item.items.push(&another_item); 
     } 
     items.push(item); 
    } 
} 

編譯器現在抱怨的another_item壽命:

error: another_item does not live long enough

for環路擁有another_item,它不能給所有權退後到的Vec引用。

不管你做什麼,你都無法解決這個根本問題。這些規則背後的一個原因是參考文獻實際上只是指針。當您將元素移入和移出items時,每個item都將更改其位置,從而使先前創建的指針無效。 (這不是Python,帶有神奇的垃圾收集引用。)當然,Rust的規則防止了這種情況的發生。

0

我這個代碼

use std::rc::Rc; 
use std::cell::RefCell; 

struct Item { 
    items: Vec<Rc<RefCell<Item>>>, 
} 

fn main() { 
    let items = vec![Item { items: Vec::new() }, Item { items: Vec::new() }]; 
    let iter = items.into_iter(); 
    let items = iter.map(|item| Rc::new(RefCell::new(item))); 
    let items = items.collect::<Vec<_>>(); 
    for item_index in 0..items.len() { 
     let item = items[item_index].clone(); 
     let mut item = item.borrow_mut(); 
     for another_item_index in 0..items.len() { 
      if another_item_index == item_index { 
       continue; 
      } 
      let another_item = items[another_item_index].clone(); 
      (*item).items.push(another_item); 
     } 
    } 
}