enum против неизменного в D

какая разница между

enum i = 2;
enum s = "Hello";

и

immutable i = 2;
immutable s = "Hello";

in D 2.0?


person user541686    schedule 25.01.2011    source источник


Ответы (2)


enum — это пользовательский тип, а не переменная. enum e = 2; — это сокращение для чего-то вроде этого enum : int { e = 2 } (т. е. анонимного перечисления с одним элементом e), см. документацию. По определению все члены анонимного перечисления помещаются в текущую область. Итак, e — это член типа, помещенный в текущую область видимости, где он ведет себя как литерал< /а>. immutable i = 2;, с другой стороны, фактически создает переменную i типа int.

Эта разница имеет несколько следствий:

Подводя итог: когда я использую константы времени компиляции, я обычно беру enum, если только эти константы не являются массивами или мне не нужна ячейка памяти по какой-то другой причине.

person stephan    schedule 25.01.2011

перечисления всегда инициализируются во время компиляции. Таким образом, им должны присваиваться значения, которые можно создать с помощью CTFE (оценка функции времени компиляции).

неизменяемые переменные могут быть инициализированы во время выполнения. Если неизменяемая переменная имеет глобальное время жизни (то есть переменные модуля, статический класс или статическая локальная переменная), то она должна быть либо инициализирована во время компиляции, либо во время выполнения с помощью статического конструктора (хотя статические локальные переменные не могут быть назначен статическим конструктором). Если неизменяемая переменная является нестатической локальной переменной, то она инициализируется во время выполнения (хотя, если значение является константой, компилятор может оптимизировать ее и инициализировать во время компиляции). Таким образом, вы можете создавать неизменяемые локальные переменные во время выполнения, в отличие от перечислений.

EDIT: Еще один случай, о котором я забыл: неизменяемые переменные-члены должны быть либо инициализированы непосредственно с помощью CTFE, либо инициализированы с помощью неизменяемого конструктора. Если неизменяемая переменная-член инициализируется непосредственно с помощью CTFE, то, очевидно, это делается во время компиляции, тогда как ее инициализация в неизменяемом конструкторе выполняется во время выполнения.

person Jonathan M Davis    schedule 25.01.2011
comment
Ага. Потому что это недопустимое выражение CTFE. В настоящее время вы не можете использовать new с CTFE. Это еще не так продвинуто. - person Jonathan M Davis; 25.01.2011
comment
Подождите, но как мне сделать неизменяемый экземпляр класса? - person user541686; 25.01.2011
comment
new immutable(Temp)() в порядке. Однако, если это переменная-член, это должно быть сделано в неизменяемом конструкторе. Вы не можете напрямую инициализировать неизменяемую переменную-член класса, потому что прямая инициализация переменной-члена должна выполняться со значением, которое генерируется CTFE, и в настоящее время вы не можете использовать new с CTFE. Итак, объявите this(/*...*/) immutable {/*...*/} и инициализируйте переменную-член внутри него. - person Jonathan M Davis; 25.01.2011