最终代码

好吧,在6000词之后,这是我们实际写成的所有代码:

  1. use std::mem;
  2. pub struct List {
  3. head: Link,
  4. }
  5. enum Link {
  6. Empty,
  7. More(Box<Node>),
  8. }
  9. struct Node {
  10. elem: i32,
  11. next: Link,
  12. }
  13. impl List {
  14. pub fn new() -> Self {
  15. List { head: Link::Empty }
  16. }
  17. pub fn push(&mut self, elem: i32) {
  18. let new_node = Box::new(Node {
  19. elem: elem,
  20. next: mem::replace(&mut self.head, Link::Empty),
  21. });
  22. self.head = Link::More(new_node);
  23. }
  24. pub fn pop(&mut self) -> Option<i32> {
  25. match mem::replace(&mut self.head, Link::Empty) {
  26. Link::Empty => None,
  27. Link::More(node) => {
  28. let node = *node;
  29. self.head = node.next;
  30. Some(node.elem)
  31. }
  32. }
  33. }
  34. }
  35. impl Drop for List {
  36. fn drop(&mut self) {
  37. let mut cur_link = mem::replace(&mut self.head, Link::Empty);
  38. while let Link::More(mut boxed_node) = cur_link {
  39. cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
  40. }
  41. }
  42. }
  43. #[cfg(test)]
  44. mod test {
  45. use super::List;
  46. #[test]
  47. fn basics() {
  48. let mut list = List::new();
  49. // Check empty list behaves right
  50. assert_eq!(list.pop(), None);
  51. // Populate list
  52. list.push(1);
  53. list.push(2);
  54. list.push(3);
  55. // Check normal removal
  56. assert_eq!(list.pop(), Some(3));
  57. assert_eq!(list.pop(), Some(2));
  58. // Push some more just to make sure nothing's corrupted
  59. list.push(4);
  60. list.push(5);
  61. // Check normal removal
  62. assert_eq!(list.pop(), Some(5));
  63. assert_eq!(list.pop(), Some(4));
  64. // Check exhaustion
  65. assert_eq!(list.pop(), Some(1));
  66. assert_eq!(list.pop(), None);
  67. }
  68. }

天。80行,而且其中的一半都是测试!嘛,我确实说过这第一个教程会花一些时间的!