Reputation: 23798
I'm using the D language, and would like to get the default value of a generic type, similar to the way default(T)
works in C#. Is this possible? If not - what are the possible workarounds?
Upvotes: 12
Views: 786
Reputation: 38297
Every type in D has a default value. It's accessed via the type's init
property. int.init
, float.init
, Object.init
, etc. In the case of a templated type, it's still the init
property. For example, if you had the generic type T
, it would be T.init
.
init
is generally the closest to an error value that the type has. For integral types, it's 0
. For bool
, it's false
. For floating point types, it's NaN
. For character types, it's \u00FF
. For references (i.e. classes) and pointers, it's null
. And in the case of structs, it's whatever the value that its member variables are directly initialized to are. e.g. In the case of
struct S
{
int a = 17;
bool b;
}
S.init
would be an instance of S
whose a
was 17
and b
was false
. Of particular note, the need for the init
property is the reason that structs in D cannot have default constructors. Their default state - that is, their init
property - must be known at compile time, whereas a constructor would be run at runtime, so the default value of a struct can't be created with a constructor, and so, while structs can have constructors, they can't have default constructors.
In the case of enums, the init
property depends on the sort of enum that it is. A manifest constant such as
enum i = 7;
would have the same init
property as its type (int
in this case), since you didn't really create a new type. However, for enums which actually create a new type, e.g.
enum E { a = 7, b = 17 };
the default value is the first value in the enum. In this case, E.init
would be a
.
Arrays are where it gets a bit interesting though. The init
property for dynamic arrays and associative arrays is null
. However, when you allocate memory for an array (be it static or dynamic), each element is initialized to its type's init
property. So, with arrays, you have both the matter of their init
value and the init
value of their elements.
In any case, the generic way to get the default value of a type is T.init
where T
is the type that you want the default value of - be it a specific type or a template parameter.
Upvotes: 12
Reputation: 78683
Re enum, according to codepad.org:
enum Foo {
a = 3,
b = 2,
}
import std.stdio;
void main() { writef("%d", Foo.init); }
gives:
3
Upvotes: 1