タプル構造体

フィールド名が重要でない場合は、タプル構造体を使用できます:

// 著作権 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

struct Point(i32, i32);

fn main() {
    let p = Point(17, 23);
    println!("({}, {})", p.0, p.1);
}

これは、単一フィールドのラッパー(newtype と呼ばれます)によく使われます:

// 著作権 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

struct PoundsOfForce(f64);
struct Newtons(f64);

fn compute_thruster_force() -> PoundsOfForce {
    todo!("Ask a rocket scientist at NASA")
}

fn set_thruster_force(force: Newtons) {
    // ...
}

fn main() {
    let force = compute_thruster_force();
    set_thruster_force(force);
}
  • newtype は、プリミティブ型の値に追加情報を持たせるための優れた方法です。 たとえば:
    • 数値が特定の単位で測定されている: 上の例の Newtons
    • 値が作成時に何らかの検証を通過しているため、使用のたびに再び 検証する必要がなくなる: PhoneNumber(String)OddNumber(u32)
  • newtype パターンについては、 「Idiomatic Rust」モジュール で詳しく扱っています。
  • newtype の単一フィールドにアクセスして、f64 の値を Newtons 型に加える方法を実演してください。
    • Rust は一般に、自動アンラップや真偽値を整数として使用することのような、 暗黙的な変換を避けます。
  • タプル構造体のフィールドが 0 個の場合、() は省略できます。結果は ゼロサイズ型(ZST)になり、その値は 1 つだけです(型名そのもの)。
    • これは、何らかの振る舞いを実装するがデータは持たない型でよく見られます (常に EOF を返すことでリーダーとしての振る舞いを実装する NullReader を想像してください)。
  • この例は、 Mars Climate Orbiter の失敗へのさりげない言及です。