型
基本データ型
予約語 | 説明 | デフォルト初期値 (.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つのfloatで表現された複素数 | 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 |
派生データ型
- ポインタ
- 配列
- 連想配列
- 関数
- デリゲート
文字列 は配列の一種です。
ユーザー定義型
- alias
- enum
- struct
- union
- class
ベース型
enum の base type とは、そのenumの基となる型のことです:
enum E : T { ... } // T は E の base type
ポインタ変換
ポインタを非ポインタにキャストしたり、その逆をすることはDでは許可されています。 しかしながら、ガベージコレクタによって割り当てられたデータを指すポインタに対しては、 この操作を行ってはいけません。
暗黙の変換
要に応じて自動的に型を変換するために、 暗黙の変換が行われます。
enum型は 暗黙のうちにベース型へ変換できますが、 逆向きは明示的な指定が必要です。 例えば
int i;
enum Foo { E }
Foo f;
i = f; // OK
f = i; // エラー
f = cast(Foo)i; // OK
f = 0; // エラー
f = Foo.E; // OK
整数の昇格
整数の昇格とは、以下の型の間の変換です:
変換前 | 変換後 |
---|---|
bool | int |
byte | int |
ubyte | int |
short | int |
ushort | int |
char | int |
wchar | int |
dchar | uint |
enum 型でベース型が左の列のものは、 右の列の型へと変換されます。
算術演算時の変換
算術二項演算子のオペランドは、 演算の前に共通の型へと変換されます。 オペランドは、 変換前に既に算術演算可能な型である必要があります。 ベース型を見ながら、次の順序で変換ルールが適用されます:
- オペランドの一方がreal型なら、 もう一方もrealへ変換される
- オペランドの一方がdoubleなら、 もう一方もdoubleへ変換される
- オペランドの一方がfloatなら、 もう一方もfloatへ変換される
- それ以外なら、次の変換のあと、
オペランド双方に整数の昇格をほどこします:
- どちらも同じ型なら、これ以上の変換はおこなわない
- 2つのオペランドのsigned/unsingedが一致していれば、 サイズの小さい型を大きい型へ変換する
- signed型の方がサイズが大きければ、小さいunsingedの方を signed型へ変換。
- signed型をunsingned型へ変換
片方ないしは両方のオペランドが enum型であったならば、 結果の型は次のルールで決まります:
- オペランド双方が同じ型の場合、 結果はその型になる
- 片方がenum でもう片方がそのベース型の場合、 結果の型はベース型になる
- 二つのオペランドが異なるenum で共通の型をベースにしている場合、 結果は、二つの型に最も近い共通のベース型になります。 ベース型が近いとは、 型からベース型への変換の列が短いことを言います。
整数値は、 整数昇格後のビットパターンを保持できないような型へ変換することはできません。 例えば:
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(long)-1; // ok, -1 は ulong で表現できる
浮動小数点数型を 暗黙に整数型へ変換することはできません。
複素浮動小数点型を 暗黙に複素数でない浮動小数点型へ変換することはできません。
虚数型は暗黙にfloat, double, real型へ変換されません。 また、 float, double, real 型が暗黙に虚数型へ変換されることもありません。
bool
bool型は1バイトの型で、 true か false のどちらかの値のみを持つことができます。 bool型に適用できる演算子は、 & | ^ &= |= ^= ! && || ?: のみです。 with false は 0、true は 1 として 任意の整数型へ暗黙に変換できます。 数値リテラル 0 と 1 は、 それぞれ bool値 false と true に暗黙変換可能です。 式をboolへとキャストするのは、数値型に対しては0のの比較 !=0 と同じ意味で、 ポインタや参照型に対しては、null との比較 !=null と同じ意味です。
デリゲート
Dには"メンバへのポインタ"はありませんが、もっと有用な delegates という概念をサポートしています。 デリゲートは オブジェクトへの参照と、非静的関数ポインタまたはクロージャやネスト関数へのポインタ、 という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) を呼ぶ
「メンバ関数ポインタ」に相当するものは、 無名のラムダ関数を使うことで構築できます:
class C {
int a;
int foo(int i) { return i + a; }
}
// mfp はメンバ関数ポインタ
auto mfp = function(C self, int i) { return self.foo(i); };
auto c = new C(); // C のインスタンスを作成
mfp(c, 1); // c.foo(1) を呼び出す
size_t と ptrdiff_t
size_t は符号なしの基本整数型のいずれかの別名で、 アドレスを取ることが可能なメモリのオフセットを表現するのに十分なサイズの型を表します。
ptrdiff_t は size_t と同じサイズの符号ありの基本整数型の別名です。