ジェネリック関数

Rust supports generics, which lets you abstract algorithms or data structures (such as sorting or a binary tree) over the types used or stored.

/// `n` の値に応じて `even` または `odd` を選択します。
fn pick<T>(n: i32, even: T, odd: T) -> T {
    if n % 2 == 0 {
        even
    } else {
        odd
    }
}

fn main() {
    println!("picked a number: {:?}", pick(97, 222, 333));
    println!("picked a string: {:?}", pick(28, "dog", "cat"));
}
This slide should take about 5 minutes.
  • Rust は引数と戻り値の型に基づいて T の型を推測します。

  • In this example we only use the primitive types i32 and &str for T, but we can use any type here, including user-defined types:

    struct Foo {
        val: u8,
    }
    
    pick(123, Foo { val: 7 }, Foo { val: 456 });
  • これは C++ テンプレートに似ていますが、Rust はジェネリック関数を部分的にすぐにコンパイルするため、その関数は制約に一致するすべての型に対して有効である必要があります。たとえば、n == 0 の場合は even + odd を返すように pick を変更してみてください。整数を使用した pick インスタンス化のみが使用されている場合でも、Rust はそれを無効とみなします。C++ ではこれを行うことができます。

  • Generic code is turned into non-generic code based on the call sites. This is a zero-cost abstraction: you get exactly the same result as if you had hand-coded the data structures without the abstraction.