やっつけな日常(36) Rustに入ればRustに従え、ジェネリック型の構造体を作ってみる

Joseph Halfmoon

前回はユニット様構造体というメンバ無、大きさゼロの構造体を見ました。でもこれ、れっきとした「具象型」でした。空だけれども型はあるのだと。今回は「なんにでもなる」ジェネリクス型の構造体を作って触ってみます。「なんにでもなる」ということは、実体が空のユニット様構造体を型パラメータにしても良いのだと。Rustは禅問答?喝!

※「やっつけな日常」投稿順 indexはこちら

いつもお世話になっております「Rust By Example 日本語版」の以下のページを参照させていただいております。

ジェネリクス

上記から1か所引用させていただきます。

ジェネリックな型パラメータを指定された場合、それは必ずジェネリック型になり、そうでなければ必ず非ジェネリック型、すなわち具象型(concrete)になります。

そういわれてもな~。実際にやってみないと身に染みませぬ。上記ページの例題をベースに勝手に拡張、動かして体感してみましたです。

実験に使用したソース

最初はいくつか構造体を定義してみました。まず、先週もやったユニット様構造体です。

struct U;

構造体のフィールドなどないのだけれど、立派な構造体であり、型だと。

その型Uを要素に持つ、タプル型構造体を定義してみます。こんな感じ。

struct B(U);

タプルというからには要素が複数になっても良いのだよね、ということでこんな感じ。

struct C(U, U);

空のUが2個も並んで何じゃらほい状態です。さらに今回は、ジェネリクス型の構造体も定義。

struct BGen<T>(T);

鍵カッコの型パラメータを与えると、その型の要素を1個もつタプルを生成するようなジェネリクス型です。

以下のコードでは、上記を使って変数を定義し、その変数や変数のメンバ、変数の型などをprintln!マクロの{:?}フォーマットで印字させてみました。

#[derive(Debug)]
struct U;

#[derive(Debug)]
struct B(U);

#[derive(Debug)]
struct C(U, U);

#[derive(Debug)]
struct BGen<T>(T);

fn type_of<T>(_: T) -> String{
  let a = std::any::type_name::<T>();
  return a.to_string();
}

fn main() {
    let u = U;
    let b = B(U);
    let c = C(U, U);
    let b_char: BGen<char> = BGen('a');
    let b_u = BGen(U);
    let b_i32 = BGen(6);
    let b_char2 = BGen('d');
    println!("u         = {:?}", u);
    println!("b         = {:?}", b);
    println!("b.0       = {:?}", b.0);
    println!("c         = {:?}", c);
    println!("c.0       = {:?}", c.0);
    println!("c.0       = {:?}", c.1);
    println!("b_char    = {:?}", b_char);
    println!("b_char.0  = {:?}", b_char.0);
    println!("b_u       = {:?}", b_u);
    println!("b_u.0     = {:?}", b_u.0);
    println!("b_i32     = {:?}", b_i32);
    println!("b_i32.0   = {:?}", b_i32.0);
    println!("b_char2   = {:?}", b_char2);
    println!("b_char2.0 = {:?}", b_char2.0);
    println!("type(b_u)    = {:?}", type_of(&b_u));
    println!("type(b_i32)  = {:?}", type_of(&b_i32));
    println!("type(b_char) = {:?}", type_of(&b_char));
    println!("type(b_char2)= {:?}", type_of(&b_char2));
}
実験結果

まずメンバを持たないユニット様構造体Uですが、立派に具象型として振舞っていることが分かります。中身にフィールドが無いと言わなければフツーの変数。

さて、ジェネリクス型は与えた型により、ジェネリクスの鍵カッコの中が切り替わっているのが分かります。UをあたえればU、整数を与えればi32、文字を与えればcharが入ります。result

エラーなく動作はしたけれども、分かったような、分からぬような。

やっつけな日常(35) Rustに入ればRustに従え、「一切メンバ無」の構造体って何よ? へ戻る

やっつけな日常(37) Rustに入ればRustに従え、唐突に Box って何よ? へ進む