Enums 枚举与D中的不可变
两者之间有什么区别Enums 枚举与D中的不可变,enums,immutability,d,Enums,Immutability,D,两者之间有什么区别 enum i = 2; enum s = "Hello"; 及 在D2.0中,枚举总是在编译时初始化。因此,必须为它们指定可通过CTFE(编译时函数求值)创建的值 不可变变量可以在运行时初始化。如果不可变变量具有全局生存期(因此它是模块变量、静态类或静态局部变量),则必须在编译时或运行时使用静态构造函数对其进行初始化(尽管静态局部变量不能使用静态构造函数进行赋值)。如果不可变变量是非静态局部变量,则在运行时对其进行初始化(尽管如果该值是常量,则编译器可能会对其进行优化,并在
enum i = 2;
enum s = "Hello";
及
在D2.0中,枚举总是在编译时初始化。因此,必须为它们指定可通过CTFE(编译时函数求值)创建的值 不可变变量可以在运行时初始化。如果不可变变量具有全局生存期(因此它是模块变量、静态类或静态局部变量),则必须在编译时或运行时使用静态构造函数对其进行初始化(尽管静态局部变量不能使用静态构造函数进行赋值)。如果不可变变量是非静态局部变量,则在运行时对其进行初始化(尽管如果该值是常量,则编译器可能会对其进行优化,并在编译时对其进行初始化)。因此,与枚举不同,您可以在运行时创建不可变的局部变量
编辑:我忘记了另一种情况:不可变成员变量必须直接用CTFE初始化,或者用不可变构造函数初始化。如果不可变成员变量是直接用CTFE初始化的,那么显然这是在编译时完成的,而在不可变构造函数中初始化它是在运行时完成的。an
enum
是用户定义的类型,而不是变量。enum e=2代码>是一个
类似于以下内容的缩写enum:int{e=2}
(即匿名
带有一个成员的枚举e
),请参阅。
根据定义,匿名枚举的所有成员都放置在当前
范围因此,e
是放置在当前作用域中的类型成员,它在当前作用域中的行为
像一只猫。
不可变i=2另一方面,code>实际上创建了int类型的变量i
。
这种差异有两个后果:
枚举e
将没有内存位置和地址(不是左值),因为
类型及其成员都没有地址。也就是说,你不能做某事
像auto-ptr=&e代码>(就像您不能执行自动ptr=&2;
)<代码>不可变
另一方面,i
是一个正常变量(只是不可变)
- ,,
不可变变量可以在编译时或运行时初始化,
而类型(其所有成员定义该类型)必须在
编译时
- 编译器只需将
e
的所有外观替换为2
。对于i
it
通常必须创建一个内存位置(尽管是优化编译器
有时可能能够避免这种情况)。因此,在
enum
的编译可能会稍微低一些,并且
二进制文件稍微小一些
- 数组之间存在着惊人的差异。对于
enumuint[2]E=[0,1]代码>和
不可变uint[2]I=[0,1]代码>可以访问枚举
,例如e[0]
比不可变
数组慢几个数量级,例如I[0]
,
尤其是当数组E
和I
变大时。这是因为对于一个
immutable
array,它只是一个普通的数组查找,比如说,一个全局数组
变量但是,对于enum
,数组似乎是每隔一天创建一次的
使用前的时间,例如,在全局枚举的函数内部(不要
问我,为什么,但编译器似乎真的只是简单地替换了外观
在本例中也使用该值)。我从未尝试过,但我会猜到
这同样适用于enum
字符串和其他非平凡类型
总而言之:当我使用编译时常量时,我通常使用enum
这些常量是数组,或者出于其他原因我需要一个内存位置。是的。因为这不是一个有效的CTFE表达式。当前不能将新建与CTFE一起使用。它还没有那么高级。等等,那么我该如何创建一个类的不可变实例呢?newimmutable(Temp)(
很好。但是,如果它是成员变量,则必须在不可变构造函数中完成。不能直接初始化不可变的类成员变量,因为直接初始化成员变量必须使用CTFE生成的值,并且当前不能将new
与CTFE一起使用。因此,声明这个(/*…*/)不可变{/*…*/}
并初始化其中的成员变量。
immutable i = 2;
immutable s = "Hello";