英語版
このページの英語版を見る

種類

文法

Dは静的に型付けされる。すべての式は型を持つ。型は、式が保持できる値を制約する。 型は式が保持できる値を制約し、それらの値に対する操作のセマンティクスを決定する。

Type:
    TypeCtorsopt BasicType TypeSuffixesopt
TypeCtors: TypeCtor TypeCtor TypeCtors
TypeCtor: const immutable inout shared
BasicType: FundamentalType . QualifiedIdentifier QualifiedIdentifier Typeof Typeof . QualifiedIdentifier TypeCtor ( Type ) Vector TraitsExpression MixinType
Vector: __vector ( VectorBaseType )
VectorBaseType: Type
FundamentalType: bool byte ubyte short ushort int uint long ulong cent ucent char wchar dchar float double real ifloat idouble ireal cfloat cdouble creal void
TypeSuffixes: TypeSuffix TypeSuffixesopt
TypeSuffix: * [ ] [ AssignExpression ] [ AssignExpression .. AssignExpression ] [ Type ] delegate Parameters MemberFunctionAttributesopt function Parameters FunctionAttributesopt
QualifiedIdentifier: Identifier Identifier . QualifiedIdentifier TemplateInstance TemplateInstance . QualifiedIdentifier Identifier [ AssignExpression ] Identifier [ AssignExpression ] . QualifiedIdentifier

基本データ型

基本データ型
KeywordDefault Initializer (.init)Description
voidデフォルトのイニシャライザがないvoid 値を持たない
boolfalseブール値
byte0符号付き8ビット
ubyte0u符号なし8ビット
short0符号あり16ビット
ushort0u符号なし16ビット
int0符号あり32ビット
uint0u符号なし32ビット
long0L符号あり64ビット
ulong0uL符号なし64ビット
cent0符号あり128ビット
ucent0u符号なし128ビット
floatfloat.nan32ビット浮動小数点
doubledouble.nan64ビット浮動小数点
realreal.nan利用可能な最大の浮動小数点サイズ
ifloatfloat.nan*1.0i虚数浮動小数点
idoubledouble.nan*1.0i虚数ダブル
irealreal.nan*1.0i虚数実数
cfloatfloat.nan+float.nan*1.0i2つの浮動小数点値からなる複素数
cdoubledouble.nan+double.nan*1.0i複素double
crealreal.nan+real.nan*1.0i複素実数
char'\xFF'符号なし8ビット(UTF-8コード単位)
wchar'\uFFFF'符号なし16ビット(UTF-16コード単位)
dchar'\U0000FFFF'符号なし32ビット(UTF-32コード単位)

基本型のエンディアンはABIの一部である。

実装定義: 実数浮動小数点型は、少なくとも。 。x86 CPUでは、x86 FPUでサポートされている80ビット拡張リアルとして実装されることが多い。 型として実装されることが多い。 double

注釈: 複素数型および虚数型ifloat,idouble,ireal,cfloat,cdouble 、 およびcreal は非推奨となり、std.complex.Complex が採用された。

派生データ型

ポインタ型

T 型へのポインタは、別のオブジェクトへの参照(アドレス)である値を持つ。 T への参照(アドレス)である値を持つ。これは一般にTへのポインタと呼ばれ、その型は次のとおりである。 T*.オブジェクトの値にアクセスするには、* の非参照演算子を使う:

int* p;

assert(p == null);
p = new int(5);
assert(p != null);

assert(*p == 5);
(*p)++;
assert(*p == 6);

ポインタにNULL値が含まれている場合、そのポインタは有効なオブジェクトを指していない。

Tへのポインタが再参照されるとき、それはヌル値を含んでいなければならない、 またはT型の有効なオブジェクトを指していなければならない。

実装定義:
  1. ヌル・ポインタが再参照されたときの動作。通常 は中断される。
未定義の振る舞い: NULLでなく、T型の有効なオブジェクトを指していないポインタを参照する。 T型の有効なオブジェクトを指していないポインタを参照すること。

既存のオブジェクトを指すようにポインターを設定するには、次の演算子を使う。 & 演算子を使う:

int i = 2;
int* p = &i;

assert(p == &i);
assert(*p == 2);
*p = 4;
assert(i == 4);

ポインタ算術」も参照のこと。

ユーザー定義型

型変換

も参照のこと:CastExpression.

ポインタの変換

ポインターは暗黙のうちにvoid* に変換される。

ポインタと非ポインタ間のキャストは許される。いくつかのポインタ・キャスト は、@safe コードでは禁止されている。

ベストプラクティス: ガベージコレクタによって割り当てられたデータを指すポインタを、非ポインタ型にキャストしないこと。 を指すポインタを、非ポインタ型にキャストしてはならない。

暗黙の変換

暗黙的変換は、必要に応じて型を自動的に変換するために使われる。 型に自動的に変換するために使われる。整数のルールは次のセクションで詳しく説明する。

列挙型は暗黙的にその基底型に変換することができる。 型に暗黙的に変換することができる。 変換が必要である。

クラスの変換

派生クラスは暗黙のうちに基底クラスに変換することができる。 には暗黙的に変換できる。例えば次のようになる:

class Base {}
class Derived : Base {}
Base bd = new Derived();              // 暗黙的変換
Derived db = cast(Derived)new Base(); // 明示的変換

派生クラスの動的配列(x )は、 と の要素が同じであれば、基底クラスの動的配列( )に暗黙的に変換できる。 xy の要素が、 と の両方であると修飾される場合、派生クラスの動的配列、例えばy を、基底クラスの動的配列、例えば に暗黙的に変換することができる。 の要素がconst またはimmutable のいずれかであるとして修飾される場合、基底クラスの動的配列に暗黙的に変換することができる。

class Base {}
class Derived : Base {}
const(Base)[] ca = (const(Derived)[]).init; // `const`要素
immutable(Base)[] ia = (immutable(Derived)[]).init; // `immutable`要素

派生クラスの静的配列、たとえばx は、 と の要素が同じであれば、暗黙のうちに基底クラスの静的配列に変換できる。 xy の要素が、 、 、またはy 、または 、または 、または 、または 、または の要素が、const またはimmutable の両方であるか、あるいはどちらも変更可能である( でも でもない)。 (const でもimmutable でもない)。

class Base {}
class Derived : Base {}
Base[3] ma = (Derived[3]).init; // 変更可能な要素
const(Base)[3] ca = (const(Derived)[3]).init; // `const`要素
immutable(Base)[3] ia = (immutable(Derived)[3]).init; // `immutable`要素

整数プロモーション

整数プロモーションは以下の型の変換である:

整数プロモーション
fromto
bool int
byte int
ubyte int
short int
ushort int
char int
wchar int
dchar uint

列挙型が左列の型のいずれかを基本型とする場合、それは右列の型に変換される。 のいずれかを基本型として持つ場合、それは右列の型に変換される。 列の型に変換される。

整数昇格は2進式の各オペランドに適用される:

void fun()
{
    byte a;
    auto b = a + a;
    static assert(is(typeof(b) == int));
    // エラー: int型の式を暗黙的にbyte型に変換できない:
    //byte c = a + a;

    ushort d;
    // エラー: int型の式を暗黙的にushort型に変換できない:
    //d = d * d;
    int e = d * d; // OK
    static assert(is(typeof(int() * d) == int));

    dchar f;
    static assert(is(typeof(f - f) == uint));
}
根拠:
  • 32ビット整数演算は、より小さな整数型よりも高速であることが多い。 よりも高速であることが多い。
  • プロモーションは、小さな整数型にありがちな偶発的なオーバーフローを避けるのに役立つ。

通常の算術変換

通常の算術変換は、二項演算子のオペランドを共通の型に変換する。 演算子を共通の型に変換する。オペランドはすでに でなければならない。 以下の規則が適用される。 を基本型から順に適用する:

  1. いずれかのオペランドがreal の場合、もう一方のオペランドは に変換される。 はreal に変換される。
  2. もしどちらかのオペランドがdouble であれば、もう一方のオペランドは に変換される。 はdouble に変換される。
  3. いずれかのオペランドがfloat の場合、もう一方のオペランドは に変換される。 はfloat に変換される。
  4. それ以外の場合は、上記の整数昇格が各オペランドに対して行われる、 が続く:
    1. 両方が同じ型の場合、それ以上の変換は行われない。
    2. 両方が符号付きまたは符号なしであれば、小さい方の型が大きい方に変換される。 小さい方の型が大きい方に変換される。
    3. 符号付き型が符号なし型より大きい場合、符号なし型は符号付き型に変換される。 型より大きい場合、符号なし型は符号付き型に変換される。
    4. 符号付き型は符号なし型に変換される。
根拠: 上記のルールはC99に準拠しており、Cからの移植が容易になっている。

Example: 符号付きと符号なしの変換:

int i;
uint u;
static assert(is(typeof(i + u) == uint));
static assert(is(typeof(short() + u) == uint));
static assert(is(typeof(ulong() + i) == ulong));
static assert(is(typeof(long() - u) == long));
static assert(is(typeof(long() * ulong()) == ulong));

Example: 浮動小数点:

float f;
static assert(is(typeof(f + ulong()) == float));

double d;
static assert(is(typeof(f * d) == double));
static assert(is(typeof(real() / d) == real));

列挙型オペレーション

オペランド型の一方または両方がenumである場合、上記の変換を経た後、結果の型は以下のように決定される。 である場合、結果の型は以下のように決定される:

  1. オペランドが同じ型であれば、結果はその型になる。 オペランドが同じ型であれば、結果はその型になる。
  2. 一方のオペランドが列挙型で、もう一方のオペランドがその列挙型の基底型であれば、結果はその基底型になる。 である場合、結果はその基底型となる。
  3. 2つのオペランドが異なる列挙型である、 の場合、結果は両者に共通する最も近い基底型となる。基底型がより近いということは、変換のシーケンスがより短くなるということである。 より近いということは、元の型から基底型に変換するシーケンスがより短いことを意味する。 への変換のシーケンスが短くなることを意味する。
enum E { a, b, c }
enum F { x, y }

void test()
{
    E e = E.a;
    e = e | E.c;
    //e = e + 4; // エラー、int型をEに代入できない
    int i = e + 4;
    e += 4; // OK、以下を参照のこと

    F f;
    //f = e | f; // エラー、Fにintを代入できない
    i = e | f;
}
注釈:上記では、e += 4演算子代入e = cast(E)(e + 4) と等価だからである。

ビットパターンを保存する

整数値は、積分後に整数ビットパターンを表現できない別の型に暗黙的に変換することはできない。 型に暗黙的に変換することはできない。 に暗黙的に変換することはできない。例:":

ubyte  u1 = -1;       // エラー、-1をubyteで表現できない
ushort u2 = -1;       // エラー、-1をushortで表現できない
uint   u3 = int(-1);  // OK、-1はintで表現でき、uintに変換できる
ulong  u4 = long(-1); // OK、-1はlongで表現でき、ulongに変換できる

値域伝播

型に基づく暗黙の変換の他に、Dでは特定の整数式を暗黙のうちに狭い型に変換することができる。 型に基づく暗黙の変換の他に、Dはある種の整数式を、整数昇格の後に、より狭い型に暗黙のうちに変換することを認めている。 に暗黙的に変換することができる。これは、各式で取り得る値の最小値と最大値を分析することで機能する。 最大値の範囲を分析する。 その値の範囲が、より狭い型の値の範囲と一致するか、そのサブセットである場合、暗黙の変換が行われる。 のサブセットである場合、暗黙の変換が許可される。 変換が許可される。コンパイル時に副式が既知である場合、暗黙的変換が許可される、 その式はさらに値の範囲を狭めることができる。

void fun(char c, int i, ubyte b)
{
    // minはc.min + 100 > short.min
    // maxはc.max + 100 < short.max
    short s = c + 100; // OK

    ubyte j = i & 0x3F; // OK、0 ... 0x3F
    //ubyte k = i & 0x14A; // エラー、0x14A > ubyte.max
    ushort k = i & 0x14A; // OK

    k = i & b; // OK、0 ... b.max
    //b = b + b; // エラー、b.max + b.max > b.max
    s = b + b; // OK、0 ... b.max + b.max
}

この実装は、以下のような変数が取り得る値の範囲を追跡しないことに注釈する。 を追跡しない:

void fun(int i)
{
    ushort s = i & 0xff; // OK
    // sは現在、0 ... 0xffではなく、s.min ... s.maxであると仮定されている
    //ubyte b = s; // エラー
    ubyte b = s & 0xff; // OK

    const int c = i & 0xff;
    // cの範囲は固定で既知である
    b = c; // OK
}

bool

bool型はバイトサイズの型であり、値true または false.

bool型のオペランドを受け取ることができる演算子は、以下のものだけである:& | ^,&= ,|= ,^=, ! && || .?:

bool の値は暗黙的に任意の積分型に変換することができる。 false は0に、true は1になる。

数値リテラル01 は、暗黙のうちにそれぞれ値 と に変換できる。bool false trueに暗黙的に変換できる。式をbool にキャストするということは、算術型の場合は または 、算術型の場合は または をテストするということである。 0 !=0 をテストし、null または!=null をテストすることである。 をテストすることを意味する。

関数型

関数型は次のような形式を持つ:

StorageClassesopt Type Parameters FunctionAttributesopt

関数型は "型 "の文法には含まれない。 関数型は例えばint(int)エイリアスすることができる。 関数型は型テストかポインタのターゲット型としてのみ使用される。

関数型をインスタンス化することは違法である。代わりに、関数へのポインタ またはデリゲートへのポインタを使うことができる。これらはそれぞれ以下のような型を持っている:

Type function Parameters FunctionAttributesopt
Type delegate Parameters MemberFunctionAttributesopt
void f(int);
alias Fun = void(int);
static assert(is(typeof(f) == Fun));
static assert(is(Fun* == void function(int)));

関数ポインタ」を参照のこと。

デリゲート

デレゲートは2つのデータの集合体である:

デリゲートは関数ポインタと同様に宣言され、初期化される:

int delegate(int) dg; // dgは関数へのデリゲートである

class OB
{
    int member(int);
}

void f(OB o)
{
    dg = &o.member; // dgはオブジェクトoとメンバ関数memberへのデリゲートである
}

デリゲートは静的メンバ関数や非メンバ関数で初期化することはできない。 または非メンバー関数で初期化することはできない。

デリゲートは関数ポインタと同様に呼ばれる:

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)を呼び出す

typeof

Typeof:
    typeof ( Expression )
    typeof ( return )

typeof の型に基づいて型を指定する方法である。 に基づいて型を指定する方法である。例:」である:

void func(int i)
{
    typeof(i) j;       // jはint型である
    typeof(3 + 6.0) x; // xはdouble型である
    typeof(1)* p;      // pはintへのポインタ型である
    int[typeof(p)] a;  // aはint[int*]型である

    writeln(typeof('c').sizeof); // 1を表示する
    double c = cast(typeof(1.0))j; // jをdoubleにキャストする
}

式は評価されず、純粋に型を生成するために使用される。 を生成するためだけに使われる:

void func()
{
    int i = 1;
    typeof(++i) j; // jはintと宣言され、iはインクリメントされない
    writeln(i);  // 1を表示する
}

もしExpressionが ValueSeqであれば であれば、各要素の型を含むTypeSeqが生成される。

特殊なケースである:

  1. typeof(return) 関数のスコープ内にある場合、 関数の戻り値の型を与える。
  2. typeof(this)の型が生成される。this は、たとえメンバ関数でなくても、staticでないメンバ関数の型を生成する。 関数の中になくても、その関数の中にあるものの型を生成する。
  3. 同様に、typeof(super)super の型を生成する。
  4. class A { }
    
    class B : A
    {
        typeof(this) x;  // xはBであると宣言されている
        typeof(super) y; // yはAと宣言されている
    }
    
    struct C
    {
        static typeof(this) z;  // zはCと宣言されている
    
        typeof(super) q; // エラー、Cのスーパー構造体がない
    }
    
    typeof(this) r;   // エラー、囲む構造体またはクラスがない
    

式がプロパティ関数の場合、typeof 、その戻り値の型が示される。

struct S
{
    @property int foo() { return 1; }
}
typeof(S.foo) n;  // nはintと宣言されている

式がテンプレートである場合、 typeof は型void を与える。

template t {}
static assert(is(typeof(t) == void));
ベストプラクティス:
  1. Typeofは、一般的な テンプレート・コードを書くときに最も役に立つ。

ミックスイン型

MixinType:
    mixin ( ArgumentList )

ArgumentListの 各AssignExpressionはコンパイル時に評価される。 はコンパイル時に評価される。 でなければならない。 結果の文字列は連結されて文字列となる。 文字列のテキストコンテンツは、有効な "としてコンパイル可能でなければならず、そのようにコンパイルされる。

void test(mixin("int")* p) // int* p
{
    mixin("int")[] a;      // int[] a;
    mixin("int[]") b;      // int[] b;
}

エイリアス型

size_t

size_t は符号なし積分基本型の1つのエイリアスである、 へのオフセットを表すのに十分な大きさの型を表す。 を表す。

ptrdiff_t

ptrdiff_t は、 と同じサイズの符号付き積分基本型のエイリアスである。size_t

string

文字列は配列の特殊なケースである。

noreturn

noreturnボトム型である。 であり、 を含む任意の型に暗黙的に変換できる。 "型の値が生成されることはなく、コンパイラはこのようなコードを最適化することができる。 型の値は決して生成されない。void noreturn

決して返さない関数は、戻り値の型を持つ。 はnoreturn を返す。これは これは、無限ループや常に例外をスローするために発生する。

noreturn abort(const(char)[] message);

int example(int i)
{
    if (i < 0)
    {
        // abortはreturnしないので、intを生成する必要はない
        int val = abort("less than zero");
    }
    // 三項式の共通型はintのままである
    return i != 0 ? 1024 / i : abort("calculation went awry.");
}

noreturn は と定義される。これは を参照すると実行が停止するからである。typeof(*null)

)