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

Joseph Halfmoon

前回、構造体を使ってみました。「構造体には3種あり」といいながら「Cみたいな」構造体と「タプルみたいな」構造体の2種のみ使用。もう一個は何なのか気になってました。そいつは「フィールドのないユニット様構造体」なんだとか。こいつ構造体といいつつフィールドは無く、サイズも0だと。どういうこと?

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

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

構造体を定義し、インスタンス化する

上記ページから1か所引用させていただきましょう。

これらは、()、ユニット型と似たような振る舞いをすることから、 ユニット様構造体と呼ばれます。ユニット様構造体は、ある型にトレイトを実装するけれども、 型自体に保持させるデータは一切ない場面に有効になります。

何を言っているのか良く分からないデス。()は「空のタプル」、そしてそれはユニット型などとも呼ばれるという理解で良いのですかね。そいつに似た構造体なので「ユニット様(よう)」なんでしょうか。

ま、実際にそのようなものを定義してみて、動かしてみることにいたします。

構造体の定義、そしてインスタンス化

大体やね、構造体っていったら、中に「メンバ」が入っているのがあたり前でしょう。メンバ無で何するの?という感じ。

定義は以下のようにしてみました。1行目の#[derive(Debug)]は度々使わせていただいている「継承」の宣言です。ぶっちゃけこう書いておくと後でprintln!マクロの中で書式指定{:?}が使えるようになり、Debugが楽と。

本体は、キャメルケース(先頭のみ大文字)で型の宣言のみと。

#[derive(Debug)] 
struct Unit;

上記では、ベタにUnitとかいう型名をつけてますが、一切メンバが無い、といいつつ型名はある、つまりは型チェックの対象になりえる、という点はタダの()じゃない、と。

上記Unit型のインスタンスの生成は以下のようにしてみました。

let u = Unit;

これで中身は空っぽの「構造体」Unit型のインスタンスの「入った」、変数 u ができると。

空っぽの構造体にトレイトを実装してみる

さて、上記のように定義し、インスタンス化できる構造体にトレイト(トレイト内にメソッドを2つ含む)を実装してみた実験コードが以下に。

#[derive(Debug)]
struct Unit;

trait Test {
    fn x2(&self, arg: i32) -> i32;
    fn x3(&self, arg: i32) -> i32;
}

impl Test for Unit {
    fn x2(&self, arg: i32) -> i32{
        arg * 2
    }

    fn x3(&self, arg: i32) -> i32{
        arg * 3
    }
}

fn main() {
    let u = Unit;
    println!("x2={}", u.x2(1));
    println!("x3={}", u.x3(1));
    println!("Unit={:?}", u);
}

上記コードを run してみたところが以下に。

Result

空っぽの構造体だけども、トレイトを実装することができました。よって、その中に持たせたメソッドを呼び出して動作させることもできる、と。なんだかトレイトの入れ物的な感じ?そういう理解でいいのですかい?

Rust、ともかく一癖あるよな。。。

やっつけな日常(34) Rustに入ればRustに従え、self.0って何?構造体とトレイト へ戻る

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