型
基本データ型
予約語 | 説明 | デフォルト初期値 (.init) |
---|---|---|
void | 形なし | - |
bool | ブール値 | false |
byte | 符号付き 8bit | 0 |
ubyte | 符号なし 8bit | 0 |
short | 符号付き 16bit | 0 |
ushort | 符号なし 16bit | 0 |
int | 符号付き 32bit | 0 |
uint | 符号なし 32bit | 0 |
long | 符号付き 64bit | 0L |
ulong | 符号なし 64bit | 0L |
cent | 符号付き 128bit (将来のために予約) | 0 |
ucent | 符号なし 128bit (将来のために予約) | 0 |
float | 32bit 浮動小数点数 | float.nan |
double | 64bit 浮動小数点数 | double.nan |
real | ハードウェアのサポートする最大の浮動小数点数 (実装メモ: x86のCPUでは80bit) または double のサイズの大きい方 | real.nan |
ifloat | float の虚数型 | float.nan * 1.0i |
idouble | double の虚数型 | double.nan * 1.0i |
ireal | real の虚数型 | real.nan * 1.0i |
cfloat | 2つのloatで表現された複素数 | float.nan + float.nan * 1.0i |
cdouble | double の複素数 | double.nan + double.nan * 1.0i |
creal | real の複素数 | real.nan + real.nan * 1.0i |
char | 符号なし 8 bit UTF-8 文字 | 0xFF |
wchar | 符号なし 16bit UTF-16 文字 | 0xFFFF |
dchar | 符号なし 32bit UTF-32 文字 | 0x0000FFFF |
構造データ型
- ポインタ
- 配列
- 連想配列
- 関数
- デリゲート
string は配列の一種です。
ユーザー定義型
- alias
- typedef
- enum
- struct
- union
- class
ベース型
enum の base type とは、そのenumの基となる型のことです:
enum E : T { ... } // T は E の base type
typedef の base type とは、その元々の型のことです:
typedef T U; // T は U の base type
ポインタ変換
ポインタを非ポインタにキャストしたり、その逆をすることはDでは許可されています。 しかしながら、ガベージコレクタによって割り当てられたデータを指すポインタに対しては、 この操作を行ってはなりません。
暗黙の変換
必要に応じて自動的に型を変換するために、 暗黙の変換が行われます。
typedefやenum型は、 暗黙のうちにベース型へ変換できますが、 逆向きは明示的な指定が必要です。 ただしリテラルは暗黙のうちにtypedefに変換されます。 例えば:
typedef int myint; int i; myint m; i = m; // OK m = i; // エラー m = cast(myint)i; // OK m = 3; // OK enum Foo { E } Foo f; i = f; // OK f = i; // エラー f = cast(Foo)i; // OK f = 0; // エラー f = E; // OK
整数の昇格
整数の昇格とは、以下の型の間の変換です:
変換前 | 変換後 |
---|---|
bool | int |
byte | int |
ubyte | int |
short | int |
ushort | int |
char | int |
wchar | int |
dchar | uint |
typedef 型や enum 型で基底型が左の列のものは、 右の列の型へと変換されます。
算術演算時の変換
算術二項演算子のオペランドは、 演算の前に共通の型へと変換されます。 オペランドは、 変換前に既に算術演算可能な型である必要があります。 typedefのベース型を見ながら、次の順序で変換ルールが適用されます:
- オペランドの一方がreal型なら、 もう一方もrealへ変換される
- オペランドの一方がdoubleなら、 もう一方もdoubleへ変換される
- オペランドの一方がfloatなら、 もう一方もfloatへ変換される
- それ以外なら、次の変換のあと、
オペランド双方に整数の昇格をほどこします:
- どちらも同じ型なら、これ以上の変換はおこなわない
- 2つのオペランドのsigned/unsingedが一致していれば、 サイズの小さい型を大きい型へ変換する
- signed型の方がサイズが大きければ、小さいunsingedの方を signed型へ変換。
- signed型をunsingned型へ変換
片方ないしは両方のオペランドが enumxかtypedef型であったならば、 結果の型は次のルールで決まります:
- オペランド双方が同じ型の場合、 結果はその型になる
- 片方がtypedefかenumでもう片方がそのベース型の場合、 結果の型はベース型になる
- 二つのオペランドが異なるenumかtypedefで共通の型をベースにしている場合、 結果は、二つの型に最も近い共通のベース型になります。 ベース型が近いとは、 型からベース型への変換の列が短いことを言います。
整数値は、 整数昇格後のビットパターンを保持できないような型へ変換することはできません。 例えば:
ubyte u1 = cast(byte)-1; // エラー。-1 はubyteで表現できない ushort u2 = cast(short)-1; // エラー。-1 はushortで表現できない uint u3 = cast(int)-1; // OK。-1 は uintで表現できる ulong u4 = cast(ulong)-1; // OK。-1 はulongで表現できる
浮動小数点数型を 暗黙に整数型へ変換することはできません。
複素浮動小数点型を 暗黙に複素数でない浮動小数点型へ変換することはできません。
虚数型は暗黙にfloat, double, real型へ変換されません。 また、 float, double, real 型が暗黙に虚数型へ変換されることもありません。
bool
bool型は1バイトの型で、 true か false のどちらかの値のみを持つことができます。 bool型に適用できる演算子は、 & | ^ &= |= ^= ! && || ?: のみです。 false は 0、true は 1 として 任意の整数型へ暗黙に変換できます。 数値リテラル 0 と 1 は、 それぞれ bool値 false と true に暗黙変換可能です。 式をboolへとキャストするのは、数値型に対しては0のの比較 !=0 と同じ意味で、 ポインタや参照型に対しては、null との比較 !=null と同じ意味です。
デリゲート
Dには"メンバへのポインタ"はありませんが、もっと有用な delegate という概念をサポートしています。デリゲートは オブジェクトへの参照と関数ポインタ、という2つの要素からなります。 そのオブジェクトへの参照が、関数呼び出しの際の this ポインタとして使用されます。
デリゲートは関数へのポインタと似た形で宣言します。 ただし、(*) の変わりに予約語 delegate を書き、 識別子は後ろに置きます。
int function(int) fp; // fp は関数へのポインタ int delegate(int) dg; // dg は関数へのデリゲート
関数ポインタを宣言する際に C 風の構文も使用できます:
int (*fp)(int); // fp は関数へのポインタ
デリゲートは関数ポインタの初期化と類似の方法で初期化します:
int func(int); fp = &func; // fpはfuncを指す class OB { int member(int); } OB o; dg = &o.member; // dg は オブジェクトoと // メンバ関数memberへのデリゲート
デリゲートを、 staticメンバ関数や非メンバ関数で初期化することはできません。
デリゲートの呼び出しは、関数ポインタの呼び出しから類推できる通りです:
fp(3); // func(3) を呼ぶ dg(3); // o.member(3) を呼ぶ