構造体 - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## 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

# 構造体

`struct`というキーワードを用いて作成できる構造体には3種類あります。

- タプル構造体。（すなわちタプルに名前が付いたようなもの）
- クラシックなC言語スタイルの構造体。
- ユニット構造体。これはフィールドを持たず、ジェネリック型を扱う際に有効です。

    // 使用されていないコードよる警告を隠すアトリビュート
    #![allow(dead_code)]

    #[derive(Debug)]
    struct Person {
        name: String,
        age: u8,
    }

    // ユニット構造体
    struct Unit;

    // タプル構造体
    struct Pair(i32, f32);

    // 2つのフィールドを持つ（クラシックな）構造体
    struct Point {
        x: f32,
        y: f32,
    }

    // 構造体は他の構造体のフィールドになることができます。
    struct Rectangle {
        // 長方形は座標空間上における左上隅と右下隅の位置によって指定できます。
        top_left: Point,
        bottom_right: Point,
    }

    fn main() {
        // 構造体をフィールド初期化の簡略記法で生成。
        let name = String::from("Peter");
        let age = 27;
        let peter = Person { name, age };

        // 構造体のデバッグ表示
        println!("{:?}", peter);

        // `Point`のインスタンス化
        let point: Point = Point { x: 5.2, y: 0.4 };
        let another_point: Point = Point { x: 10.3, y: 0.2 };

        // pointのフィールドにアクセスします。
        println!("point coordinates: ({}, {})", point.x, point.y);

        // 構造体の更新記法を用いて、別の構造体のフィールドの値を基に
        // 新たなpointを生成。
        let bottom_right = Point { x: 10.3, ..another_point };

        // `bottom_right.y`の値は`another_point.y`と同一ですが、
        // これは`another_point`のフィールドの値を用いて生成したためです。
        println!("second point: ({}, {})", bottom_right.x, bottom_right.y);

        // `let`を使用してpointをデストラクトします。
        let Point { x: left_edge, y: top_edge } = point;

        let _rectangle = Rectangle {
            // 構造体の定義とインスタンスの作成を同時に行います。
            top_left: Point { x: left_edge, y: top_edge },
            bottom_right: bottom_right,
        };

        // ユニット構造体のインスタンス化
        let _unit = Unit;

        // タプル構造体のインスタンス化
        let pair = Pair(1, 0.1);

        // タプル構造体のフィールドにアクセス
        println!("pair contains {:?} and {:?}", pair.0, pair.1);

        // タプル構造体のデストラクト
        let Pair(integer, decimal) = pair;

        println!("pair contains {:?} and {:?}", integer, decimal);
    }

### 演習

1. `Rectangle`の面積を計算する`rect_area`関数を追加してください。ネストしたデストラクトを使ってみましょう。
2. `Point`と`f32`を引数とし、`Rectangle`を返す`square`関数を追加してください。`Rectangle`の左上の点が`Point`になり、`f32`が`Rectangle`の幅と高さになります。

### 参照

アトリビュート, 生識別子, デストラクト