## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# テストケース：連結リスト

`enum`の使用が適切なパターンのひとつに、連結リストを作成する場合があります。

    use crate::List::*;

    enum List {
        // Cons：要素をラップし、次の要素へのポインタを保持するタプル構造体
        Cons(u32, Box<List>),
        // Nil：連結リストの終端であることを示すノード
        Nil,
    }

    // 列挙型にはメソッドを付与することができます。
    impl List {
        // 空リストの作成
        fn new() -> List {
            // `Nil`は`List`型を持ちます。
            Nil
        }

        // リストを受け取り、その始端に新しい要素を付加したものを返す関数
        fn prepend(self, elem: u32) -> List {
            // この`Cons`自体も、その第2要素もどちらもList型です。
            Cons(elem, Box::new(self))
        }

        // リストの長さを返すメソッド
        fn len(&self) -> u32 {
            // `self` has to be matched, because the behavior of this method
            // depends on the variant of `self`
            // `self` has type `&List`, and `*self` has type `List`, matching on a
            // concrete type `T` is preferred over a match on a reference `&T`
            // after Rust 2018 you can use self here and tail (with no ref) below as well,
            // rust will infer &s and ref tail.
            // See https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/default-match-bindings.html
            match *self {
                // Can't take ownership of the tail, because `self` is borrowed;
                // instead take a reference to the tail
                // And it'a a non-tail recursive call which may cause stack overflow for long lists.
                Cons(_, ref tail) => 1 + tail.len(),
                // 空リストならば長さは0
                Nil => 0
            }
        }

        // リストをヒープ上の文字列として表したものを返すメソッド
        fn stringify(&self) -> String {
            match *self {
                Cons(head, ref tail) => {
                    // `format!`は`print!`に似ていますが、コンソール上に出力
                    // する代わりに、ヒープ上の文字列を返します。
                    format!("{}, {}", head, tail.stringify())
                },
                Nil => {
                    format!("Nil")
                },
            }
        }
    }

    fn main() {
        // 空の連結リストを作成。
        let mut list = List::new();

        // 要素を追加。
        list = list.prepend(1);
        list = list.prepend(2);
        list = list.prepend(3);

        // 追加後の状態を表示。
        println!("linked list has length: {}", list.len());
        println!("{}", list.stringify());
    }

### 参照

`Box`, メソッド