Ответ 1
An enum
- это определяемый пользователем тип, а не переменная. enum e = 2;
- это
короткую руку для чего-то вроде этого enum : int { e = 2 }
(т.е. анонимного
перечисление с одним членом e
), см. документацию.
По определению все члены анонимного перечисления помещаются в текущий
объем. Таким образом, e
является членом типа, помещенным в текущую область действия, где он ведет себя
как literal.
immutable i = 2;
, с другой стороны, фактически создает переменную i
типа int.
Это различие имеет несколько следствий:
-
enum e
не будет иметь место для памяти и нет адреса (не является lvalue), поскольку ни тип, ни его члены не имеют адреса. То есть вы ничего не можете сделать напримерauto ptr = &e;
(так же, как вы не можете сделатьauto ptr = &2;
).immutable i
С другой стороны, это нормальная переменная (просто неизменная). - Как обсуждалось Джонатаном, неизменяемые переменные могут быть инициализированы во время компиляции или во время выполнения, тогда как тип (со всеми его членами, определяющими тип) должен быть известен в время компиляции.
- Компилятор может просто заменить все элементы
e
на2
. Дляi
это обычно необходимо создать ячейку памяти (хотя оптимизирующий компилятор возможно, сможет избежать этого иногда). По этой причине рабочая нагрузка во время можно ожидать, что компиляция дляenum
будет несколько ниже, и несколько меньше. - Существует удивительная разница для массивов. Для
enum uint[2] E = [0, 1];
иimmutable uint[2] I = [0, 1];
доступ кenum
, например.E[0]
, может на порядок медленнее, чем для массиваimmutable
, например.I[0]
особенно когда массивыe
иi
становятся больше. Это происходит потому, что дляimmutable
, это обычный поиск массива, скажем, глобального переменная. Дляenum
однако похоже, что массив создается каждый времени до его использования, например. внутри функции для глобальногоenum
(не спросите меня, почему, но компилятор действительно просто заменяет внешний вид со значением в этом случае тоже). Я никогда не пробовал, но догадывался, что то же самое относится к строкамenum
и другим нетривиальным типам.
Подводя итог: когда я использую константы времени компиляции, я обычно беру enum
, если только
эти константы являются массивами или мне нужна ячейка памяти по какой-то другой причине.