1.8 最终代码

原文链接: https://rust-unofficial.github.io/too-many-lists/first-final.html

好了,写了 6000 字之后,这是我们实际写出来的全部代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::mem;

pub struct List {
    head: Link,
}

enum Link {
    Empty,
    More(Box<Node>),
}

struct Node {
    elem: i32,
    next: Link,
}

impl List {
    pub fn new() -> Self {
        List { head: Link::Empty }
    }

    pub fn push(&mut self, elem: i32) {
        let new_node = Box::new(Node {
            elem: elem,
            next: mem::replace(&mut self.head, Link::Empty),
        });

        self.head = Link::More(new_node);
    }

    pub fn pop(&mut self) -> Option<i32> {
        match mem::replace(&mut self.head, Link::Empty) {
            Link::Empty => None,
            Link::More(node) => {
                self.head = node.next;
                Some(node.elem)
            }
        }
    }
}

impl Drop for List {
    fn drop(&mut self) {
        let mut cur_link = mem::replace(&mut self.head, Link::Empty);

        while let Link::More(mut boxed_node) = cur_link {
            cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
        }
    }
}

#[cfg(test)]
mod test {
    use super::List;

    #[test]
    fn basics() {
        let mut list = List::new();

        // 检查空链表行为正确
        assert_eq!(list.pop(), None);

        // 填充链表
        list.push(1);
        list.push(2);
        list.push(3);

        // 检查正常弹出
        assert_eq!(list.pop(), Some(3));
        assert_eq!(list.pop(), Some(2));

        // 再推入一些,确保没有损坏
        list.push(4);
        list.push(5);

        // 检查正常弹出
        assert_eq!(list.pop(), Some(5));
        assert_eq!(list.pop(), Some(4));

        // 检查耗尽
        assert_eq!(list.pop(), Some(1));
        assert_eq!(list.pop(), None);
    }
}

天哪。80 行,一半还是测试!好吧,我说过第一个会花挺长时间的!

最后修改 August 23, 2026: 更新 (499855b16)