上一章写了最小的链表,但有不足和需要改进的地方

  • 避免重复发明轮子:使用 Option
  • 让链表可用于任何元素类型:泛型
  • 添加 peek 方法:生命周期
  • 让链表可迭代:迭代器

    1 Option

    1. enum Link{
    2. Empty,
    3. More(Box<Node>)
    4. }
    5. // 等价于
    6. type Link = Option<Box<Node>>
  • 上一节的Link实际上就是Option<Box<Node>>

  • 可以用类型别名来将Link改成Option
  • 将上一节的first.rs复制成second.rs,然后:
    • type Link = Option<Box<Node>>
    • 字符串替换:Link::More —> Link::Some
    • 字符串替换:Link::Empty —> Link::None

      2 Option::take():取走值,留下None```rust

      pub fn push(&mut self, val: i32) { let node = Node { elem: val, //next: mem::replace(&mut self.head, Link::None), next: self.head.take(), }; self.head = Link::Some(Box::new(node)); }

pub fn pop(&mut self) -> Option { // 两种写法都可以 // match mem::replace(&mut self.head, Link::None) { match self.head.take() { Link::None => None, /Link::Some(ref mut node) => { mem::swap(&mut self.head, &mut node.next); Some(node.elem) }/ // 两种写法都可以 Link::Some(node) => { self.head = node.next; Some(node.elem) } } }

fn drop(&mut self) { //let mut cur_link = mem::replace(&mut self.head, Link::None); let mut cur_link = self.head.take(); while let Link::Some(mut boxed_node) = cur_link { //cur_link = mem::replace(&mut boxed_node.next, Link::None); cur_link = boxed_node.next.take(); } }

  1. <a name="SmGLC"></a>
  2. # 3 Option::map():映射成另一种Option```rust
  3. pub fn pop(&mut self) -> Option<i32> {
  4. // 两种写法都可以
  5. // match mem::replace(&mut self.head, Link::None) {
  6. /*
  7. match self.head.take() {
  8. Link::None => None,
  9. Link::Some(ref mut node) => {
  10. mem::swap(&mut self.head, &mut node.next);
  11. Some(node.elem)
  12. }
  13. // 两种写法都可以
  14. Link::Some(node) => {
  15. self.head = node.next;
  16. Some(node.elem)
  17. }
  18. }
  19. */
  20. // 使用 Option::map()
  21. // 注意: map() 要求所有权;node 的类型是 Box<Node>
  22. self.head.take().map(|node| {
  23. self.head = node.next;
  24. node.elem
  25. })
  26. }