Подтвердить что ты не робот

Как получить значение по умолчанию для общего типа?

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

4b9b3361

Ответ 1

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

Ответ 2

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

init, как правило, является самым близким к значению ошибки, которое имеет тип. Для интегральных типов оно 0. Для bool it 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 - это тип, который вы хотите использовать по умолчанию - будь то конкретный тип или параметр шаблона.

Ответ 3

Re enum, согласно codepad.org:

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

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

дает:

3