|
@@ -0,0 +1,65 @@
|
|
|
|
|
+use std::mem;
|
|
|
|
|
+
|
|
|
|
|
+/// `List` 列表
|
|
|
|
|
+pub struct List {
|
|
|
|
|
+ head: Link,
|
|
|
|
|
+}
|
|
|
|
|
+struct Node {
|
|
|
|
|
+ elem: i32,
|
|
|
|
|
+ next: Link,
|
|
|
|
|
+}
|
|
|
|
|
+enum Link {
|
|
|
|
|
+ Empty,
|
|
|
|
|
+ More(Box<Node>),
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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 Default for List {
|
|
|
|
|
+ fn default() -> Self {
|
|
|
|
|
+ Self { head: Link::Empty }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+mod test {
|
|
|
|
|
+ use crate::first;
|
|
|
|
|
+
|
|
|
|
|
+ #[test]
|
|
|
|
|
+ fn basics() {
|
|
|
|
|
+ let mut list = first::List::new();
|
|
|
|
|
+
|
|
|
|
|
+ // Check empty list behaves right
|
|
|
|
|
+ assert_eq!(list.pop(), None);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // Populate list
|
|
|
|
|
+ list.push(1);
|
|
|
|
|
+ list.push(2);
|
|
|
|
|
+ list.push(3);
|
|
|
|
|
+
|
|
|
|
|
+ // Check normal removal
|
|
|
|
|
+ assert_eq!(list.pop(), Some(3));
|
|
|
|
|
+ assert_eq!(list.pop(), Some(2));
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+}
|