Every symbol, type, and expression has properties that can be queried:
| Property | Description |
|---|---|
| .mangleof | string representing the ‘mangled’ representation of the type |
| .stringof | string representing the source representation of the type |
| Expression | Value |
|---|---|
| int.mangleof | yields the string "i" |
| int.stringof | yields the string "int" |
| (1+2).stringof | yields the string "1 + 2" |
Every type has properties that can be queried. Every expression also has these properties, which are equivalent to the properties of the expression's type. These properties are:
| Property | Description |
|---|---|
| .init | initializer |
| .sizeof | size in bytes |
| .alignof | alignment size |
| Expression | Value |
|---|---|
| int.init | yields 0 |
| int.sizeof | yields 4 |
| (3).sizeof | yields 4 (because 3 is an int) |
| Property | Description |
|---|---|
| .max | maximum value |
| .min | minimum value |
| Property | Description |
|---|---|
| .infinity | infinity value |
| .nan | NaN -Not a Number value (other NaN values can be produced) |
| .dig | number of decimal digits of precision |
| .epsilon | smallest increment to the value 1 |
| .mant_dig | number of bits in mantissa |
| .max_10_exp | maximum int value such that 10max_10_exp is representable |
| .max_exp | maximum int value such that 2max_exp-1 is representable |
| .min_10_exp | minimum int value such that 10min_10_exp is representable as a normalized value |
| .min_exp | minimum int value such that 2min_exp-1 is representable as a normalized value |
| .max | largest representable value that's not infinity |
| .min_normal | smallest representable normalized value that's not 0 |
| .re | real part |
| .im | imaginary part |
| Expression | Value |
|---|---|
| float.nan | yields the floating point NaN value |
| (2.5F).nan | yields the floating point NaN value |
See:
See:
.init produces a constant expression that is the default initializer. If applied to a type, it is the default initializer for that type. If applied to a variable or field, it is the default initializer for that variable or field's type. The default values for different kinds of types are described below:
| Type | .init Value |
|---|---|
| char | '\xff' |
| dchar | '\xffff' |
| wchar | '\xffff' |
| Enum | first member value |
| Integers | 0 |
| Floating Point | NaN |
| Reference Types | null |
| Structs | eachfield's default value |
| Unions | first member value |
int a;int b = 1;staticassert(int.init == 0);staticassert(a.init == 0);staticassert(b.init == 0);struct Foo{int a;int b = 7;}staticassert(Foo.init.a == 0);staticassert(Foo.init.b == 7);
Note that.init produces a default initialized object, not a default constructed one. If there is a default constructor for an object, it may produce a different value.
void main(){int x;struct S {void foo() { x = 1; }// access x in enclosing scope via context pointer } S s1;// OK. S() correctly initialize its context pointer. S s2 = S();// OK. same as s1 s1.foo();// OK S s3 = S.init;// Bad. the context pointer in s3 is null s3.foo();// Access violation}
struct S{int x; @disablethis();this(int n) { x = n; }invariant {assert(x > 0); }void check() {}}void main(){//S s1; // Error: variable s1 initializer required for type S//S s2 = S(); // Error: constructor S.this is not callable// because it is annotated with @disable S s3 = S.init;// Bad. s3.x == 0, and it violates the invariant of S s3.check();// Assertion failure}
.stringof produces a constant string that is the source representation of its prefix. If applied to a type, it is the string for that type. If applied to an expression, it is the source representation of that expression. The expression will not be evaluated.
module test;import std.stdio;struct Dog { }enum Color { Red }int i = 4;void main(){ writeln((1+2).stringof);// "1 + 2" writeln(test.stringof);// "module test" writeln(Dog.stringof);// "Dog" writeln(int.stringof);// "int" writeln((int*[5][]).stringof);// "int*[5][]" writeln(Color.Red.stringof);// "Red" writeln((5).stringof);// "5" writeln((++i).stringof);// "i += 1"assert(i == 4);// `++i` was not evaluated}
e.sizeof gives the size in bytes of the expressione.
When getting the size of a member, it is not necessary for there to be athis object:
struct S{int a;}staticassert(S.a.sizeof == 4);staticassert(Object.sizeof == (void*).sizeof);
.sizeof applied to a class object returns the size of the class reference, not the class instantiation.
See also:__traits(classInstanceSize).
.alignof gives the aligned size of an expression or type. For example, an aligned size of 1 means that it is aligned on a byte boundary, 4 means it is aligned on a 32 bit boundary.
Seethealign attribute for an example.
Mangling refers to how a symbol is represented in text form in the generated object file..mangleof returns a string literal of the representation of the type or symbol it is applied to. The mangling of types and symbols with D linkage is defined byName Mangling.
.classinfo provides information about the dynamic type of a classobject. It returns a reference to typeobject.TypeInfo_Class.
.classinfo applied to an interface gives the information for theinterface, not the class it might be an instance of.
.tupleof provides a symbol sequence of all the non-static fields in a struct or class.The order of the fields in the tuple matches the order in which the fields are declared.
For classes, hidden fields and fields of the bass class are excluded.A common use case is to iterate over the fields with aforeach loop.struct Vector3{int x, y, z;}void test(){ Vector3 v = Vector3(5, 10, 15);float sum = 0;foreach(num; v.tupleof) { sum+= num; } writeln(sum);//30}
User-defined properties can be created usingProperty Functions.