• 测试实例:链表
    • 参见:

    测试实例:链表

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

    1. use List::*;
    2. enum List {
    3. // Cons: 元组结构体,包含一个元素和一个指向下一节点的指针
    4. Cons(u32, Box<List>),
    5. // Nil: 末结点,表明链表结束
    6. Nil,
    7. }
    8. // 方法可以在 enum 定义
    9. impl List {
    10. // 创建一个空列表
    11. fn new() -> List {
    12. // `Nil` 为 `List` 类型
    13. Nil
    14. }
    15. // 处理一个列表,得到一个头部带上一个新元素的同样类型的列表并返回此值
    16. fn prepend(self, elem: u32) -> List {
    17. // `Cons` 同样为 List 类型
    18. Cons(elem, Box::new(self))
    19. }
    20. // 返回列表的长度
    21. fn len(&self) -> u32 {
    22. // `self` 必须匹配,因为这个方法的行为取决于 `self` 的变化类型
    23. // `self` 为 `&List` 类型,`*self` 为 `List` 类型,一个具体的 `T` 类型的匹配
    24. // 要参考引用 `&T` 的匹配
    25. match *self {
    26. // 不能得到 tail 的所有权,因为 `self` 是借用的;
    27. // 而是得到一个 tail 引用
    28. Cons(_, ref tail) => 1 + tail.len(),
    29. // 基本情形:空列表的长度为 0
    30. Nil => 0
    31. }
    32. }
    33. // 将列表以字符串(堆分配的)的形式返回
    34. fn stringify(&self) -> String {
    35. match *self {
    36. Cons(head, ref tail) => {
    37. // `format!` 和 `print!` 类似,但返回的是一个堆分配的字符串,而不是
    38. // 打印结果到控制台上
    39. format!("{}, {}", head, tail.stringify())
    40. },
    41. Nil => {
    42. format!("Nil")
    43. },
    44. }
    45. }
    46. }
    47. fn main() {
    48. // 创建一个空链表
    49. let mut list = List::new();
    50. // 追加一些元素
    51. list = list.prepend(1);
    52. list = list.prepend(2);
    53. list = list.prepend(3);
    54. // 显示链表的最后状态
    55. println!("linked list has length: {}", list.len());
    56. println!("{}", list.stringify());
    57. }

    参见:

    Box 和 方法