Как получить значение по умолчанию для универсального типа? - PullRequest
12 голосов
/ 30 августа 2011

Я использую язык D и хотел бы получить значение по умолчанию универсального типа, аналогично тому, как default(T) работает в C #.Это возможно?Если нет - каковы возможные обходные пути?

Ответы [ 3 ]

12 голосов
/ 30 августа 2011

Каждый тип в D имеет значение по умолчанию. Доступ к нему осуществляется через свойство init типа. int.init, float.init, Object.init и т. Д. В случае шаблонного типа это все еще свойство init. Например, если у вас есть универсальный тип T, это будет T.init.

init обычно наиболее близко к значению ошибки, которое имеет тип. Для целочисленных типов это 0. Для bool это false. Для типов с плавающей запятой это NaN. Для типов символов это \u00FF. Для ссылок (то есть классов) и указателей это null. А в случае структур это то значение, которому непосредственно инициализируются его переменные-члены. например В случае

struct S
{
    int a = 17;
    bool b;
}

S.init будет экземпляром S, у которого a было 17, а b было false. Особо следует отметить, что необходимость в свойстве init является причиной того, что структуры в D не могут иметь конструкторы по умолчанию. Их состояние по умолчанию, то есть их свойство init, должно быть известно во время компиляции, тогда как конструктор будет запускаться во время выполнения, поэтому значение по умолчанию для структуры не может быть создано с помощью конструктора, и поэтому, пока структуры могут иметь конструкторы, они не могут иметь конструкторы по умолчанию.

В случае перечислений свойство init зависит от вида перечисления. Константа манифеста, такая как

enum i = 7;

будет иметь то же свойство init, что и его тип (в данном случае int), поскольку вы на самом деле не создали новый тип. Однако для перечислений, которые фактически создают новый тип, например

enum E {a = 7, b = 17};

значением по умолчанию является первое значение в перечислении. В этом случае E.init будет a.

Массивы - то, где это становится немного интересным. Свойство init для динамических и ассоциативных массивов равно null. Однако, когда вы выделяете память для массива (будь то статический или динамический), каждый элемент инициализируется свойством init своего типа. Итак, с массивами у вас есть как значение их init, так и значение init их элементов.

В любом случае, общий способ получить значение по умолчанию для типа: T.init, где T - это тип, для которого требуется значение по умолчанию - будь то определенный тип или параметр шаблона.

12 голосов
/ 30 августа 2011

Я думаю T.init может быть то, что вы ищете.

1 голос
/ 31 августа 2011

Перечислим, согласно codepad.org :

enum Foo {
  a = 3,
  b = 2,
}

import std.stdio;
void main() { writef("%d", Foo.init); }

дает:

3

...