列挙型
EnumDeclaration: enum Identifier EnumBody enum Identifier : EnumBaseType EnumBody AnonymousEnumDeclaration EnumBaseType: Type EnumBody: { EnumMembers } ; EnumMembers: EnumMember EnumMember , EnumMember , EnumMembers EnumMember: EnumMemberAttributesopt Identifier EnumMemberAttributesopt Identifier = AssignExpression EnumMemberAttributes: EnumMemberAttribute EnumMemberAttribute EnumMemberAttributes EnumMemberAttribute: DeprecatedAttribute UserDefinedAttribute @disable
AnonymousEnumDeclaration: enum : EnumBaseType { EnumMembers } enum { AnonymousEnumMembers } AnonymousEnumMembers: AnonymousEnumMember AnonymousEnumMember , AnonymousEnumMember , AnonymousEnumMembers AnonymousEnumMember: EnumMember EnumMemberAttributesopt Type Identifier = AssignExpression
列挙型宣言は、定数のグループを定義するために使用される。
列挙型(Named Enum)
名前付き列挙型" は、関連する定数を宣言するために使用される。 定数を宣言し、一意の型を与えてグループ化するために使用される。 EnumMembersは、名前付き列挙型のスコープで宣言される。名前付き enumは新しい型を宣言し、すべてのEnumMembersはその型を持つ。
これは新しい型X を定義している。 X.A=0 X.B=1 X.C=2 を持つ:
enum X { A, B, C } // 名前付き列挙型
EnumBaseTypeが明示的に設定されておらず、最初の EnumMemberが AssignExpressionを持つ場合、その型が設定される。 に設定される。そうでない場合、デフォルトは 型int に設定される。
- 名前付き列挙型メンバは、そのEnumBaseType に暗黙的にキャストできる。
- EnumBaseTypeインスタンスを名前付き列挙型に暗黙的にキャストすることはできない。
int i; enum Foo { E } Foo f; i = f; // OK f = i; // エラー f = cast(Foo)i; // OK f = 0; // エラー f = Foo.E; // OK
名前付き列挙型メンバは個別の型を持たない。
EnumMemberの値は、AssignExpression が存在する場合は、その AssignExpression で指定される。 AssignExpression がなく、それが最初のEnumMember である場合、その値は EnumMember 型に変換される、 その値は0 からEnumBaseTypeに変換される。 AssignExpressionがなく、最初のEnumMember でもない場合、その値は直前の EnumBaseType の値に変換される、 には、直前のEnumMember+1 の値が与えられる:
- 前のEnumMemberの値がEnumBaseTypeの場合.max 、 の場合はエラーとなる。これは値のオーバーフローを防ぐためである。前の コンパイル時にEnumBaseType.max と比較できない場合はエラーとなる。
- 基本型がコンパイル時に評価可能な演算を定義していない場合はエラーである。 評価可能な+1 操作を定義していない場合はエラーとなる。
- 直前のEnumMember+1 の値が、直前のEnumBaseType の値と同じである。 の値と同じ場合はエラーとなる。(これは これは浮動小数点型で起こりうる)。
enum E : char { a, b = char.max, c // オーバーフロー } static assert(E.a == 0);
すべてのEnumMemberは AssignExpressionsのスコープ内にある。
enum A = 3; enum B { A = A // エラー、循環参照 } enum C { A = B, // A = 4 B = D, // B = 4 C = 3, // C = 3 D // D = 4 } enum E : C { E1 = C.D, E2 // エラー、C.DはC.maxである }
空の列挙型本体は、不透明な列挙型を意味する。
enum X; // 不透明な列挙型 writeln(X.init); // エラー: 列挙型Xは不透明であり、デフォルトのイニシャライザを持たない
列挙型変数
変数は名前付き列挙型にすることができる。 デフォルトのイニシャライザは、enum型で定義された最初のメンバである。
enum X { A=3, B, C } X x; assert(x == X.A); x |= X.B; assert(x & X.A);
オペランドの型が異なる場合に実行される二項演算の結果型は、ここで定義される。 ここで定義される。
こちらも参照のこと: final switch.
列挙型プロパティ
列挙型プロパティは名前付き列挙型にのみ存在する。
.init | 最初の列挙型メンバーの値 |
.min | 最小列挙型値 |
.max | 最大の列挙型メンバ値 |
.sizeof | 列挙値のストレージサイズ |
例:":
enum X { A=3, B=1, C=4, D, E=2 } X.init // is X.A X.min // is X.B X.max // is X.D X.sizeof // int.sizeofと同じである
名前付き列挙型のEnumBaseTypeは比較をサポートしなければならない。 .max .min をサポートしなければならない。
列挙型のコピーと代入
名前付き列挙型はコピーコンストラクタを持たない。 コピーコンストラクタを持たない、 ポストブリット ID 代入のオーバーロードを持つことはない、 たとえEnumBaseType で定義されていてもである。
基本型がstruct である名前付き列挙型をコピーする場合、コピーコンストラクタは呼び出されない。 である名前付き列挙値をコピーする場合、コピーコンストラクタは呼び出されない:
struct S { this(ref S rhs) { assert(0); } } enum E : S { A = S.init } void main() { E e1; E e2 = e1; // OK - コピーコンストラクタが呼び出されていない }
基底型がstruct である名前付き列挙型をコピーする場合、コピーコンストラクタは呼び出されない。 を持つ名前付き列挙値をコピーする場合、ポストブリットは呼び出されない:
struct S { this(this) { assert(0); } } enum E : S { A = S.init } void main() { E e1; E e2 = e1; // OK - postblitが呼び出されない }
名前付き列挙型値を同じ型の別のオブジェクトに代入するとき、それらのオブジェクトの基底型がポストブリットである場合、ポストブリットは呼び出されない。 名前付き列挙値を同じ型の別のオブジェクトに代入するとき、それらの値の基本型がstruct 、identity代入オーバーロードがある場合、identity代入オーバーロードは呼び出されない。 を持つ場合、identity assignment overload は呼び出されない:
struct S { void opAssign(S rhs) { assert(0); } } enum E : S { A = S.init } void main() { E e1, e2; e2 = e1; // OK - opAssignが呼び出されない }
匿名列挙型
列挙型識別子が存在しない場合、その列挙型は匿名列挙型である。 は匿名列挙型であり、EnumMembersは EnumDecifier のスコープで宣言される。 が宣言される。 新しい型は作成されない。
EnumMembersは異なる型を持つことができる。 それらの型は、of.EnumMembersの最初の部分で指定される:
- 型がある場合は、その型によって与えられる。EnumBaseTypeが存在する場合、型は許されない。 EnumBaseTypeが存在する場合、型は許可されない。
- EnumBaseType が存在する場合。
- AssignExpression の型(存在する場合)。
- 前のEnumMember の型(存在する場合)。
- int
enum { A, B, C } // anonymous enum
定数A=0, B=1, C=2、すべてint 型を定義する。
列挙型は少なくとも1つのメンバを持たなければならない。
EnumMemberの値は、AssignExpressionが存在すれば、それによって与えられる。 AssignExpressionがなく、それが最初のEnumMemberである場合、その値は、 .init その値はEnumMemberの"@property"型である。 AssignExpressionがなく、それが最初のEnumMember でない場合、その値は前の EnumMember の値になる、 には、前のEnumMember+1 の値が与えられる:
- 前のEnumMemberの値が.max " プロパティである。 である場合はエラーとなる。 これは値のオーバーフローを防ぐためである。前の メンバがコンパイル時に.max プロパティと比較できない場合はエラーとなる。
- 前のメンバの型がコンパイル時に評価可能な 操作を定義していない場合はエラーとなる。 評価可能な+1 操作を定義していない場合はエラーとなる。
- 前のEnumMemberの値+1 が、前のEnumMemberの値 と同じ場合はエラーである。 の値と同じ場合はエラーとなる。(これは これは浮動小数点型で起こりうる)。
すべてのEnumMemberは AssignExpressionsのスコープ内にある。
enum { A, B = 5+7, C, D = 8+C, E }
A=0、B=12、C=13、D=21、E=22、すべてint 。
enum : long { A = 3, B }
A=3、B=4、すべてlong 。
enum : string { A = "hello", B = "betty", C // エラー、"betty"に1を追加できない }
enum { A = 1.2f, // Aはfloat型の1.2fである B, // Bはfloat型の2.2fである int C = 3, // Cはint型の3である D // Dはint型の4である }
単一メンバー構文
無名列挙型のメンバが1つだけの場合、{ } は省略できる。 を省略できる。文法的に言えば、これは自動宣言である。
enum i = 4; // iはint型の4である enum long l = 3; // lはlong型の3である
マニフェスト定数
列挙型定数は、コンパイル時にのみ存在する。
マニフェスト定数はl値ではない。 を取ることはできない。 これらはコンパイラのメモリ内にのみ存在する。
enum size = __traits(classInstanceSize, Foo); // コンパイル時に評価される
マニフェスト定数のイニシャライザーは、コンパイル時の関数評価によって評価される。
template Foo(T) { // 悪くないが、'size'変数は実行ファイルに配置される。 const size_t size = T.sizeof; // コンパイル時に評価される // ... コンパイル時に'size'を使用する ... } template Bar(T) { // Better, マニフェスト定数は実行可能ファイル内に実行時の場所を持たない。 enum size_t size = T.sizeof; // コンパイル時に評価される // ... コンパイル時に'size'を使用する。 ... // Foo!T.sizeのアドレスを取ると、それが実行ファイルに入る。 auto p = &Foo!T.size; }
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku