📝
too-many-list-zh
  • 目录
  • 介绍
  • 一个糟糕的单链栈
    • 布局
    • New
    • 所有权
    • Push
    • Pop
    • 测试
    • Drop
    • 最终代码
  • 一个还行的单链栈
    • Option
    • Generic
    • Peek
    • IntoIter
    • Iter
    • IterMut
    • 最终代码
  • 一个不可变栈
    • 布局
    • 基础
    • Drop
    • Arc
    • 最终代码
  • 一个糟糕但安全的双向队列
    • 布局
    • 构建
    • 任务分解
    • Peek
    • 对称情况
    • Iteration
    • 最终代码
  • 一个不安全的队列
    • 布局
    • UnSafe
    • 基础
    • 拓展
    • 最终代码
  • 一个还行不安全双向队列
  • 一堆无聊的清单
    • 双重单链表
Powered by GitBook
On this page

Was this helpful?

  1. 一个糟糕但安全的双向队列

布局

我们设计的关键是RefCell类型。 RefCell的核心是一对方法:

fn borrow(&self) -> Ref<'_, T>;
fn borrow_mut(&self) -> RefMut<'_, T>;

borrow 和 borrow_mut 的规则正是 & 和 &mut 的规则:您可以根据需要多次调用borrow,但是borrow_mut 需要排他性。

RefCell 不是静态地强制执行此操作,而是在运行时强制执行它们。 如果您违反了规则,RefCell 将会发生 panic 并使程序崩溃。 为什么返回 Ref 和 RefMut 这些东西? 好吧,它们的行为本质上类似于 Rcs,只是为了借用。 他们还将 RefCell 借用,直到超出范围。 我们稍后再讨论。

现在,有了Rc和RefCell,我们可以成为……一种无法收集周期冗长而普遍可变的垃圾收集语言! Y-yaaaaay ...

我们希望成为双链接。 这意味着每个节点都有一个指向上一个和下一个节点的指针。 同样,列表本身具有指向第一个和最后一个节点的指针。 这使我们可以在列表的两端快速插入和删除。

所以我们可能想要这样的东西:

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

pub struct List<T> {
    head: Link<T>,
    tail: Link<T>,
}

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

struct Node<T> {
    elem: T,
    next: Link<T>,
    prev: Link<T>,
}
> cargo build

warning: field is never used: `head`
 --> src/fourth.rs:5:5
  |
5 |     head: Link<T>,
  |     ^^^^^^^^^^^^^
  |
  = note: #[warn(dead_code)] on by default

warning: field is never used: `tail`
 --> src/fourth.rs:6:5
  |
6 |     tail: Link<T>,
  |     ^^^^^^^^^^^^^

warning: field is never used: `elem`
  --> src/fourth.rs:12:5
   |
12 |     elem: T,
   |     ^^^^^^^

warning: field is never used: `next`
  --> src/fourth.rs:13:5
   |
13 |     next: Link<T>,
   |     ^^^^^^^^^^^^^

warning: field is never used: `prev`
  --> src/fourth.rs:14:5
   |
14 |     prev: Link<T>,
   |     ^^^^^^^^^^^^^

嘿,它构建了! 有很多未使用警告代码,但它构建了! 让我们试着使用它。

Previous一个糟糕但安全的双向队列Next构建

Last updated 4 years ago

Was this helpful?