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

問題

コンテナ型に対してジェネリックな trait には、型指定の要件があります。trait のユーザーは、そのジェネリック型をすべて指定しなければなりません。

以下の例では、Contains trait はジェネリック型 AB の使用を許可しています。その後、このトレイトは Container 型に対して実装され、ABi32 を指定することで、fn difference() で使用できるようにしています。

Contains はジェネリックであるため、fn difference() に対してジェネリック型を すべて 明示的に記述することを強制されます。実際には、AB入力 C によって決定されることを表現する方法が必要です。次のセクションで見るように、関連型はまさにその機能を提供します。

struct Container(i32, i32);

// 2つのアイテムがコンテナ内に格納されているかをチェックするトレイト。
// また、最初または最後の値を取得する。
trait Contains<A, B> {
    fn contains(&self, _: &A, _: &B) -> bool; // `A` と `B` を明示的に要求する。
    fn first(&self) -> i32; // `A` や `B` を明示的には要求しない。
    fn last(&self) -> i32;  // `A` や `B` を明示的には要求しない。
}

impl Contains<i32, i32> for Container {
    // 格納されている数値が等しい場合は真。
    fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
        (&self.0 == number_1) && (&self.1 == number_2)
    }

    // 最初の数値を取得する。
    fn first(&self) -> i32 { self.0 }

    // 最後の数値を取得する。
    fn last(&self) -> i32 { self.1 }
}

// `C` は `A` と `B` を含んでいる。そのことを踏まえると、`A` と
// `B` を再度表現しなければならないのは煩わしい。
fn difference<A, B, C>(container: &C) -> i32 where
    C: Contains<A, B> {
    container.last() - container.first()
}

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

    let container = Container(number_1, number_2);

    println!("コンテナは {} と {} を含んでいますか: {}",
        &number_1, &number_2,
        container.contains(&number_1, &number_2));
    println!("最初の数値: {}", container.first());
    println!("最後の数値: {}", container.last());

    println!("差は: {}", difference(&container));
}

関連項目:

structtrait