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实际上创建了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";