module pind.samples.ja.union_.union_2; import std.stdio; import std.exception; struct Discriminated { private: TypeInfo validType_; union { int i_; double d_; } public: this(int value) { // これは、以下のプロパティ関数の呼び出しである: i = value; } // 'int'データのセッター void i(int value) { i_ = value; validType_ = typeid(int); } // 'int'データのゲッター int i() const { enforce(validType_ == typeid(int), "The data is not an 'int'."); return i_; } this(double value) { // これは、以下のプロパティ関数の呼び出しである: d = value; } // 'double'データのセッター void d(double value) { d_ = value; validType_ = typeid(double); } // 'double'データのゲッター double d() const { enforce(validType_ == typeid(double), "The data is not a 'double'." ); return d_; } // 有効なデータの型を識別する const(TypeInfo) type() const { return validType_; } } unittest { // 'int'データから始めましょう auto var = Discriminated(42); // 型は'int'として報告されるはず assert(var.type == typeid(int)); // 'int'ゲッターは動作するはず assert(var.i == 42); // 'double'ゲッターは失敗するはず assertThrown(var.d); // 'int'を'double'データに置き換えよう var.d = 1.5; // 型は'double'として報告されるはず assert(var.type == typeid(double)); // これで'double'ゲッターは動作するはず... assert(var.d == 1.5); // ...そして'int'ゲッターは失敗するはず assertThrown(var.i); } void main() { Discriminated[] arr = [ Discriminated(1), Discriminated(2.5) ]; foreach (value; arr) { if (value.type == typeid(int)) { writeln("Working with an 'int' : ", value.i); } else if (value.type == typeid(double)) { writeln("Working with a 'double': ", value.d); } else { assert(0); } } }