種類
文法
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
基本データ型
Keyword | Default Initializer (.init) | Description |
---|---|---|
void | デフォルトのイニシャライザがない | void 値を持たない |
bool | false | ブール値 |
byte | 0 | 符号付き8ビット |
ubyte | 0u | 符号なし8ビット |
short | 0 | 符号あり16ビット |
ushort | 0u | 符号なし16ビット |
int | 0 | 符号あり32ビット |
uint | 0u | 符号なし32ビット |
long | 0L | 符号あり64ビット |
ulong | 0uL | 符号なし64ビット |
cent | 0 | 符号あり128ビット |
ucent | 0u | 符号なし128ビット |
float | float.nan | 32ビット浮動小数点 |
double | double.nan | 64ビット浮動小数点 |
real | real.nan | 利用可能な最大の浮動小数点サイズ |
ifloat | float.nan*1.0i | 虚数浮動小数点 |
idouble | double.nan*1.0i | 虚数ダブル |
ireal | real.nan*1.0i | 虚数実数 |
cfloat | float.nan+float.nan*1.0i | 2つの浮動小数点値からなる複素数 |
cdouble | double.nan+double.nan*1.0i | 複素double |
creal | real.nan+real.nan*1.0i | 複素実数 |
char | '\xFF' | 符号なし8ビット(UTF-8コード単位) |
wchar | '\uFFFF' | 符号なし16ビット(UTF-16コード単位) |
dchar | '\U0000FFFF' | 符号なし32ビット(UTF-32コード単位) |
基本型のエンディアンはABIの一部である。
注釈: 複素数型および虚数型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型の有効なオブジェクトを指していなければならない。
- ヌル・ポインタが再参照されたときの動作。通常 は中断される。
既存のオブジェクトを指すようにポインターを設定するには、次の演算子を使う。 & 演算子を使う:
int i = 2; int* p = &i; assert(p == &i); assert(*p == 2); *p = 4; assert(i == 4);
ポインタ算術」も参照のこと。
ユーザー定義型
型変換
も参照のこと:CastExpression.ポインタの変換
ポインターは暗黙のうちにvoid* に変換される。
ポインタと非ポインタ間のキャストは許される。いくつかのポインタ・キャスト は、@safe コードでは禁止されている。
暗黙の変換
暗黙的変換は、必要に応じて型を自動的に変換するために使われる。 型に自動的に変換するために使われる。整数のルールは次のセクションで詳しく説明する。
列挙型は暗黙的にその基底型に変換することができる。 型に暗黙的に変換することができる。 変換が必要である。
- すべての型は暗黙のうちに次のように変換される。 noreturn.
- 静的配列と動的配列は暗黙的に void[].
- 関数ポインタとデリゲートは. は共変数に変換できる。
クラスの変換
派生クラスは暗黙のうちに基底クラスに変換することができる。 には暗黙的に変換できる。例えば次のようになる:
class Base {} class Derived : Base {} Base bd = new Derived(); // 暗黙的変換 Derived db = cast(Derived)new Base(); // 明示的変換
派生クラスの動的配列(x )は、 と の要素が同じであれば、基底クラスの動的配列( )に暗黙的に変換できる。 x とy の要素が、 と の両方であると修飾される場合、派生クラスの動的配列、例えばy を、基底クラスの動的配列、例えば に暗黙的に変換することができる。 の要素がconst またはimmutable のいずれかであるとして修飾される場合、基底クラスの動的配列に暗黙的に変換することができる。
class Base {} class Derived : Base {} const(Base)[] ca = (const(Derived)[]).init; // `const`要素 immutable(Base)[] ia = (immutable(Derived)[]).init; // `immutable`要素
派生クラスの静的配列、たとえばx は、 と の要素が同じであれば、暗黙のうちに基底クラスの静的配列に変換できる。 x 、y の要素が、 、 、または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`要素
整数プロモーション
整数プロモーションは以下の型の変換である:
from | to |
---|---|
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ビット整数演算は、より小さな整数型よりも高速であることが多い。 よりも高速であることが多い。
- プロモーションは、小さな整数型にありがちな偶発的なオーバーフローを避けるのに役立つ。
通常の算術変換
通常の算術変換は、二項演算子のオペランドを共通の型に変換する。 演算子を共通の型に変換する。オペランドはすでに でなければならない。 以下の規則が適用される。 を基本型から順に適用する:
- いずれかのオペランドがreal の場合、もう一方のオペランドは に変換される。 はreal に変換される。
- もしどちらかのオペランドがdouble であれば、もう一方のオペランドは に変換される。 はdouble に変換される。
- いずれかのオペランドがfloat の場合、もう一方のオペランドは に変換される。 はfloat に変換される。
- それ以外の場合は、上記の整数昇格が各オペランドに対して行われる、
が続く:
- 両方が同じ型の場合、それ以上の変換は行われない。
- 両方が符号付きまたは符号なしであれば、小さい方の型が大きい方に変換される。 小さい方の型が大きい方に変換される。
- 符号付き型が符号なし型より大きい場合、符号なし型は符号付き型に変換される。 型より大きい場合、符号なし型は符号付き型に変換される。
- 符号付き型は符号なし型に変換される。
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である場合、上記の変換を経た後、結果の型は以下のように決定される。 である場合、結果の型は以下のように決定される:
- オペランドが同じ型であれば、結果はその型になる。 オペランドが同じ型であれば、結果はその型になる。
- 一方のオペランドが列挙型で、もう一方のオペランドがその列挙型の基底型であれば、結果はその基底型になる。 である場合、結果はその基底型となる。
- 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; }
ビットパターンを保存する
整数値は、積分後に整数ビットパターンを表現できない別の型に暗黙的に変換することはできない。 型に暗黙的に変換することはできない。 に暗黙的に変換することはできない。例:":
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 }
- 詳しくはdmcの記事を参照のこと。
- https://en.wikipedia.org/wiki/Value_range_analysis も参照のこと。
bool
bool型はバイトサイズの型であり、値true または false.
bool型のオペランドを受け取ることができる演算子は、以下のものだけである:& | ^,&= ,|= ,^=, ! && || .?:
bool の値は暗黙的に任意の積分型に変換することができる。 false は0に、true は1になる。
数値リテラル0 と1 は、暗黙のうちにそれぞれ値 と に変換できる。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つのデータの集合体である:
- オブジェクトへの参照と、静的でないメンバ関数へのポインタである。 静的でないメンバ関数へのポインタ。
- クロージャへのポインタと、ネストされた関数へのポインタ。 ネストされた関数へのポインタ。 オブジェクト参照は、関数が呼び出されたときにthis 。
デリゲートは関数ポインタと同様に宣言され、初期化される:
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が生成される。
特殊なケースである:
- typeof(return) 関数のスコープ内にある場合、 関数の戻り値の型を与える。
- typeof(this)の型が生成される。this は、たとえメンバ関数でなくても、staticでないメンバ関数の型を生成する。 関数の中になくても、その関数の中にあるものの型を生成する。
- 同様に、typeof(super) 。 super の型を生成する。
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));
- 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)
)DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku