2017-08-06 59 views
0

我正在嘗試爲隊列實現dequeue函數,但我很困惑借用檢查器是如何工作的。我在這段代碼中做錯了什麼?我在這段代碼中做了什麼錯誤來實現一個隊列的`dequeue`函數?

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

type Link<T> = Option<Rc<RefCell<Node<T>>>>; 

struct Node<T>{ 
    item: T, 
    next: Link<T> 
} 
pub struct Queue<T>{ 
    first: Link<T>, 
    last: Link<T>, 
    length: usize 
} 

impl<T> Queue<T>{ 
    pub fn new() -> Queue<T> { 
     Queue { 
      first: None, 
      last: None, 
      length: 0 
     } 
    } 
    pub fn is_empty(&self) -> bool { 
     self.length == 0 
    } 
    pub fn size(&self) -> usize { 
     self.length 
    } 
    pub fn enqueue(&mut self, item: T) { 
     let temp = self.last.take(); 
     self.last = Some(Rc::new(RefCell::new(Node{ 
      item, 
      next: None 
     }))); 
     if self.is_empty() { 
      self.first = self.last.clone(); 
     } else { 
      let temp = temp.unwrap(); 
      temp.borrow_mut().next = self.last.clone(); 
     } 
     self.length += 1; 
    } 
    pub fn dequeue(&mut self) -> Result<T, String>{ 
     if let Some(ref mut value) = self.first.take() { 
      let mut temp = *(value.borrow_mut()); 
      let next = *(temp.next.unwrap().borrow_mut()); 
      let old_value = replace(&mut temp, next); 
      return Ok(old_value.item); 
     } 
     Err("Queue is empty".to_owned()) 
    } 
} 

在獲得一個可變參考值內Some,我要與正在通過的節點的next字段引用的節點來替換。我是否需要取得Some內的價值所有權?我可以這樣做嗎?

回答

1

這裏是dequeue的實現:

pub fn dequeue(&mut self) -> Result<T, String> { 
    // First, disconnect `self.last` from the element it is pointing, 
    // since it will have to be updated anyway. If there is no elemen in the 
    // queue, we're done. 
    let first = try!(self.first.take().ok_or("Queue is empty".to_owned())); 
    // if there are two Rc's pointing to this node, then this must be the 
    // only node, so `self.last` has to go 
    if Rc::strong_count(&first) == 2 { 
     self.last = None; 
    } 
    let first_node = Rc::try_unwrap(first).ok().expect(
     "This should be the only owner of the node" 
    ).into_inner(); 
    self.first = first_node.next; 
    self.length -= 1; 
    Ok(first_node.item) 
} 

Here is the complete code。我還添加了一個dequeue_back用於使這個幾乎是一個雙端隊列和一些測試。

+0

嘿謝謝。出院也很高興。 :d – codeNoob