【问题标题】:What am I doing wrong in this code to implement a `dequeue` function for a queue?我在这段代码中做错了什么来为队列实现“出队”功能?
【发布时间】:2017-08-06 09:09:58
【问题描述】:

我正在尝试为队列实现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 中的值的所有权?我什至可以这样做吗?

【问题讨论】:

    标签: rust queue ownership borrow-checker


    【解决方案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 以使这几乎成为一个双端队列和一些测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2015-04-23
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      • 2012-02-11
      相关资源
      最近更新 更多