Rust ジェネリクス機能の探究

RustRustBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、ジェネリクスのトピックを探ります。ジェネリクスとは、型と機能を汎用化して、より幅広いケースを処理し、コードの重複を減らすことができます。Rust のジェネリクスの構文では、角括弧を使って型パラメータを指定します。たとえば <T> のようにです。ジェネリクスを使うことで、任意の型の引数を受け取ることができる汎用関数を作成できます。さらに、異なる具体的な型と共に動作する汎用型を定義することもできます。

注: 実験でファイル名が指定されていない場合、好きなファイル名を使うことができます。たとえば、main.rs を使って、rustc main.rs &&./main でコンパイルして実行することができます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/integer_types -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/type_casting -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/function_syntax -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/expressions_statements -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/lifetime_specifiers -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} rust/operator_overloading -.-> lab-99344{{"Rust ジェネリクス機能の探究"}} end

ジェネリクス

「ジェネリクス」は、型と機能をより広範なケースに汎用化するトピックです。これは、多くの点でコードの重複を減らすために非常に役立ちますが、かなり複雑な構文を必要とする場合があります。つまり、ジェネリックであることは、ジェネリック型が実際に有効と見なされる型をどのように指定するかについて非常に注意深く対応する必要があります。ジェネリクスの最も単純で一般的な用途は、型パラメータです。

型パラメータは、角括弧と大文字を使ってジェネリックとして指定されます。
通常は <T> と表されます。Rust では、「ジェネリック」は、1つ以上のジェネリック型パラメータ <T> を受け取るものを指します。ジェネリック型パラメータとして指定される任意の型はジェネリックであり、それ以外のすべては具体的(非ジェネリック)です。

たとえば、任意の型の引数 T を受け取る名前 foo の「汎用関数」を定義すると:

fn foo<T>(arg: T) {... }

T<T> を使ってジェネリック型パラメータとして指定されているため、ここで (arg: T) として使用される場合、それはジェネリックと見なされます。T が以前に struct として定義されていた場合でも、この場合が当てはまります。

この例は、いくつかの構文の使い方を示しています:

// 具体的な型 `A`。
struct A;

// 型 `Single` を定義する際、`A` の最初の使用の前に `<A>` がありません。
// したがって、`Single` は具体的な型であり、`A` は上記のように定義されています。
struct Single(A);
//            ^ ここが `Single` が型 `A` を最初に使用する箇所です。

// ここでは、`<T>` が `T` の最初の使用の前にあるため、`SingleGen` はジェネリック型です。
// 型パラメータ `T` はジェネリックであるため、何でもかまいません。
// ここでは、一番上で定義された具体的な型 `A` も含まれます。
struct SingleGen<T>(T);

fn main() {
    // `Single` は具体的で、明示的に `A` を受け取ります。
    let _s = Single(A);

    // 型 `SingleGen<char>` の変数 `_char` を作成し、
    // それに `SingleGen('a')` の値を与えます。
    // ここでは、`SingleGen` に明示的に型パラメータが指定されています。
    let _char: SingleGen<char> = SingleGen('a');

    // `SingleGen` には、暗黙的に型パラメータを指定することもできます:
    let _t    = SingleGen(A); // 一番上で定義された `A` を使用します。
    let _i32  = SingleGen(6); // `i32` を使用します。
    let _char = SingleGen('a'); // `char` を使用します。
}

まとめ

おめでとうございます!あなたはジェネリクスの実験を完了しました。あなたのスキルを向上させるために、LabExでさらに多くの実験を行って練習することができます。