2014-04-17 20 views
5

aşağıdaki gibi görünür karşılıklı özyinelemeli ağaç yapısı vardır:Pas ödünç işaretçileri ve ömürleri Benim kod

enum Child<'r> { 
    A(&'r Node<'r>), 
    B, 
    C 
} 

struct Node<'r> { 
    children : [&'r Child<'r>,..25] 
} 

impl <'r>Node<'r> { 
    fn new() -> Node { 
     Node { 
      children : [&B,..25] 
     } 
    } 
} 

ama olduğu gibi o derleme değil. Bunu yapmak için değiştirmenin en iyi yolu nedir?

cevap

4

Düğümlerin ağaç dışından değiştirilebileceği bir sürüm var.

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

struct Node { 
    a : Option<Rc<RefCell<Node>>>, 
    b : Option<Rc<RefCell<Node>>>, 
    value: int 
} 

impl Node { 
    fn new(value: int) -> Rc<RefCell<Node>> { 
     let node = Node { 
      a: None, 
      b: None, 
      value: value 
     }; 
     Rc::new(RefCell::new(node)) 
    } 
} 


fn main() { 
    let first = Node::new(0); 
    let second = Node::new(0); 
    let third = Node::new(0); 

    first.borrow_mut().a = Some(second.clone()); 
    second.borrow_mut().a = Some(third.clone()); 

    second.borrow_mut().value = 1; 
    third.borrow_mut().value = 2; 

    println!("Value of second: {}", first.borrow().a.get_ref().borrow().value); 
    println!("Value of third: {}", first.borrow().a.get_ref().borrow().a.get_ref().borrow().value); 
} 

Rc

referans sayılan işaretçidir ve tek bir nesne birden fazla sahibi olmasını sağlar. Bununla birlikte, mutasyona izin vermez, bu nedenle çalışma zamanı kontrol edilebilir değişken borçlanmaya izin veren bir RefCell gereklidir. Bu nedenle bu kod Rc<RefCell<Node>> kullanıyor. Opsiyon tipi, Option<Rc<RefCell<Node>>> ile potansiyel çocukları temsil etmek için kullanılır.

Rc tipi otomatik dereferences olduğundan, doğrudan RefCell yöntemlerini çağırmak mümkündür. Bunlar, alttaki Düğüme bir referans ve mutable referans veren borrow() ve borrow_mut()'dur. Ayrıca, başarısız olamayan try_borrow() ve try_borrow_mut() varyantları da vardır.

get_ref(), temeldeki Rc<RefCell<Node>>'a bir başvuru döndüren Seçenek türünde bir yöntemdir. Gerçek bir peogramda, muhtemelen Option'un önceden bir şey içerip içermediğini kontrol etmek isteriz.

Orijinal kod neden çalışmıyor? Referanslar &T mülkiyeti reddetmektedir, bu nedenle başka bir şey düğümlere sahip olmak zorunda kalacaktır. &Node türünde bir ağaç inşa etmek mümkün olsa da, ağacın dışındaki düğümleri değiştirmek mümkün olmayacaktır, çünkü bir kez ödünç alındığında, bir nesne borç alan nesneden başka bir şeyle değiştirilemez.

+1

Niçin çalıştığını açıklayabilir misiniz ve yapmadı mı? –

+0

Değiştirilebilecek Düğüme ihtiyacım var. – user1502040