测试实例:链表

enum 的一个常见用法就是创建链表(linked-list):

1. use List::*;

3. enum List {
4. // Cons:元组结构体,包含链表的一个元素和一个指向下一节点的指针
5. Cons(u32, Box<List>),
6. // Nil:末结点,表明链表结束
7. Nil,
8. }

10. // 可以为 enum 定义方法
11. impl List {
12. // 创建一个空的 List 实例
13. fn new() -> List {
14. // `Nil` 为 `List` 类型(译注:因 `Nil` 的完整名称是 `List::Nil`)
15. Nil
16. }

18. // 处理一个 List,在其头部插入新元素,并返回该 List
19. fn prepend(self, elem: u32) -> List {
20. // `Cons` 同样为 List 类型
21. Cons(elem, Box::new(self))
22. }

24. // 返回 List 的长度
25. fn len(&self) -> u32 {
26. // 必须对 `self` 进行匹配(match),因为这个方法的行为取决于 `self` 的
27. // 取值种类。
28. // `self` 为 `&List` 类型,`*self` 为 `List` 类型,匹配一个具体的 `T`
29. // 类型要好过匹配引用 `&T`。
30. match *self {
31. // 不能得到 tail 的所有权,因为 `self` 是借用的;
32. // 因此使用一个对 tail 的引用
33. Cons(_, ref tail) => 1 + tail.len(),
34. // (递归的)基准情形(base case):一个长度为 0 的空列表
35. Nil => 0
36. }
37. }

39. // 返回列表的字符串表示(该字符串是堆分配的)
40. fn stringify(&self) -> String {
41. match *self {
42. Cons(head, ref tail) => {
43. // `format!` 和 `print!` 类似,但返回的是一个堆分配的字符串,
44. // 而不是打印结果到控制台上
45. format!("{}, {}", head, tail.stringify())
46. },
47. Nil => {
48. format!("Nil")
49. },
50. }
51. }
52. }

54. fn main() {
55. // 创建一个空链表
56. let mut list = List::new();

58. // 追加一些元素
59. list = list.prepend(1);
60. list = list.prepend(2);
61. list = list.prepend(3);

63. // 显示链表的最后状态
64. println!("linked list has length: {}", list.len());
65. println!("{}", list.stringify());
66. }

参见:

Box 和 方法