Dmitri Nesteruk
Dmitri Nesteruk

Reputation: 23798

How do I get the default value of a generic type?

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

Answers (3)

Jonathan M Davis
Jonathan M Davis

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

BCS
BCS

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

user791139
user791139

Reputation: 281

I think T.init might be what you're looking for.

Upvotes: 12

Related Questions