関連型 - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## 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

# 関連型

関連型を使用すると、コンテナ型の中の要素をトレイトの中に 出力型 として書くことで、全体の可読性を上げることができます。トレイトを定義する際の構文は以下のようになります。

    #![allow(unused)]
    fn main() {
    // `A`と`B`は`type`キーワードを用いてトレイト内で宣言されています。
    // （注意：この文脈で使用する`type`は型エイリアスを宣言する際の`type`とは
    // 異なることに注意しましょう。）
    trait Contains {
        type A;
        type B;

        // これらの新しい型をジェネリックに使用するために、構文が
        // アップデートされています。
        fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
    }
    }

`Contains`トレイトを使用する関数において、`A`と`B`を明示する必要がなくなっていることに注目しましょう。

    // 関連型を使用しない場合
    fn difference<A, B, C>(container: &C) -> i32 where
        C: Contains<A, B> { ... }

    // 使用する場合
    fn difference<C: Contains>(container: &C) -> i32 { ... }

前セクションの例を関連型を使用して書きなおしてみましょう。

    struct Container(i32, i32);

    // ２つの要素がコンテナ型の中にあることをチェックするトレイト
    // また、最初と最後の値を取得することもできます。
    trait Contains {
        // メソッドが使用できるジェネリック型を定義。
        type A;
        type B;

        fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
        fn first(&self) -> i32;
        fn last(&self) -> i32;
    }

    impl Contains for Container {
        // `A`と`B`がどの型であるかを明示。入力型（訳注：つまり`Self`の型）
        // が`Container(i32, i32)`である場合、出力型は`i32`と`i32`となります。
        type A = i32;
        type B = i32;

        // `&i32`の代わりに`&Self::A`または`&Self::B`と書いても構いません
        fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
            (&self.0 == number_1) && (&self.1 == number_2)
        }
        // ひとつ目の値を取得。
        fn first(&self) -> i32 { self.0 }

        // 最後（2つめ）の値を取得。
        fn last(&self) -> i32 { self.1 }
    }

    fn difference<C: Contains>(container: &C) -> i32 {
        container.last() - container.first()
    }

    fn main() {
        let number_1 = 3;
        let number_2 = 10;

        let container = Container(number_1, number_2);

        println!("Does container contain {} and {}: {}",
            &number_1, &number_2,
            container.contains(&number_1, &number_2));
        println!("First number: {}", container.first());
        println!("Last number: {}", container.last());

        println!("The difference is: {}", difference(&container));
    }