オフィスアワーがそろそろ始まるよ!()

共用体

共用体は異なる複数のデータ型を、1つのデータ型として定義するものです。共用体は列挙型と組み合わせたタグ付き共用体として利用することで、その真価を発揮します。タグ付き共用体については、次節で紹介します。

ここでは、共用体の基本事項だけを説明します。

共用体の定義

共用体型の定義は、const 型名 = union { ヴァリアント, ... };で行います。

examples/ch03-user-defined-types/src/union.zen:4:8

const Number = union {
    U64: u64,
    I64: i64,
    F64: f64,
};

共用体のインスタンスは、const / var インスタンス名 = 共用体型{ .ヴァリアント名 = 式 };で定義します。また、インスタンスの値へのアクセスは、インスタンス名.ヴァリアント名で行います。

examples/ch03-user-defined-types/src/union.zen:10:12

test "define union" {
    var i = Number{ .U64 = 0 };
    ok(i.U64 == 0);

共用体のインスタンスは、ある時点では1つのヴァリアントとして振る舞います。他のヴァリアントとして振る舞うようにするには、共用体インスタンス自体を再代入します。

examples/ch03-user-defined-types/src/union.zen:10:19

test "define union" {
    var i = Number{ .U64 = 0 };
    ok(i.U64 == 0);

    i = Number { .I64 = -1 };
    ok(i.I64 == -1);

    i = Number { .F64 = 1.234 };
    ok(i.F64 == 1.234);
}

型安全性

Zenの共用体は型安全です。ある時点では1つのヴァリアントとして振る舞い、他のヴァリアントとして利用することはできません。コンパイラが安全性を検証できる範囲ではコンパイルエラーに、そうでない範囲は実行時に安全性の検証が行われます。

    var i = Number{ .U64 = 0 };
    i.F64 = 1.234;

上記コードは、次のコンパイルエラーになります。

error[E07002]: use of undeclared identifier 'Number'
    var i = Number{ .U64 = 0 };
            ~

次のコードは、安全性保護付き未定義動作により、実行時にパニックが発生します。

fn giveMeUnsignedNumber(num: Number) void {
    ok(num.U64 == 0);
}

test "type safety in runtime" {
    var signed = Number { .I64 = 0 };
    giveMeUnsignedNumber(signed);
}

☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2019 connectFree Corporation. All rights reserved.
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.