D 中的枚举与不可变

发布于 2024-10-13 21:16:26 字数 164 浏览 6 评论 0原文

D 2.0有什么区别

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

D 2.0和

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

What's the difference between

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

and

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

in D 2.0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风向决定发型 2024-10-20 21:16:26

enum 是用户定义的类型,而不是变量。 enum e = 2; 是一个
像这样的简写 enum : int { e = 2 } (即匿名
具有一个成员 e 的枚举),请参阅文档
根据定义,匿名枚举的所有成员都被放入当前
范围。因此,e 是放置在当前作用域中的类型成员,其行为在当前作用域中
就像文字
另一方面,immutable i = 2; 实际上创建了一个 int 类型的变量 i

这种差异会带来几个后果:

  • enum e 将没有内存位置和地址(没有左值),因为
    类型及其成员都没有地址。即你不能做某事
    就像 auto ptr = &e; (就像你不能做 auto ptr = &2;)。 不可变
    另一方面,i 是一个普通变量(只是不可变)。
  • 正如乔纳森所讨论的
    不可变变量可以在编译时或运行时初始化,
    而类型(及其定义该类型的所有成员)必须已知
    编译时间。
  • 编译器可以简单地将所有出现的 e 替换为 2。对于
    通常必须创建一个内存位置(尽管优化编译器
    有时也许可以避免这种情况)。为此,期间的工作量
    enum 的编译预计会稍微低一些,并且
    二进制稍微小一些。
  • 数组有一个令人惊讶的差异。对于 enum uint[2] E = [0, 1];
    immutable uint[2] I = [0, 1];enum的访问,例如E[0],可以
    immutable 数组慢几个数量级,例如 I[0]
    特别是当数组 EI 变得更大时。之所以如此,是因为对于
    immutable 数组,它只是一个普通的数组查找,比如全局数组
    多变的。然而,对于 enum 来说,数组似乎是每隔
    使用之前的时间,例如在全局enum的函数内(不要
    问我为什么,不过编译器确实好像只是简单的替换了外观
    也具有本例中的值)。我从未尝试过,但我猜想
    这同样适用于 enum 字符串和其他重要类型。

总结一下:当我使用编译时常量时,我​​通常采用 enum 除非
这些常量是数组,或者由于其他原因我需要一个内存位置。

An enum is a user-defined type, not a variable. enum e = 2; is a
short-hand for something like this enum : int { e = 2 } (i.e. an anonymous
enum with one member e), see the documentation.
By definition, all members of an anonymous enum are placed into the current
scope. So, e is a type member placed into the current scope, where it behaves
like a literal.
immutable i = 2; on the other hand actually creates a variable i of type int.

This difference has a couple of consequences:

  • enum e will have no memory location and no address (is no lvalue), since
    neither a type nor its members have an address. I.e. you cannot do something
    like auto ptr = &e; (just like you cannot do auto ptr = &2;). immutable
    i
    on the other hand is a normal variable (just immutable).
  • As discussed by Jonathan,
    immutable variables can be initialized at compile time or at run-time,
    whereas a type (with all its members defining the type) must be known at
    compile time.
  • The compiler can simply replace all appearances of e with 2. For i it
    usually has to create a memory location (although an optimizing compiler
    might be able to avoid this sometimes). For this reason, the workload during
    compilation for an enum might be expected to be somewhat lower, and the
    binary somewhat smaller.
  • There is a surprising difference for arrays. For enum uint[2] E = [0, 1]; and
    immutable uint[2] I = [0, 1]; the access to the enum, e.g. E[0], can
    be orders of magnitude slower than for the immutable array, e.g. I[0],
    especially as the arrays E and I get bigger. This is so because for an
    immutable array, it is just a normal array lookup to, say, a global
    variable. For the enum however it looks like the array gets created every
    time before it gets used, e.g. inside a function for a global enum (don't
    ask me, why, but the compiler really seems to simply replace the appearance
    with the value in this case, too). I have never tried but would guess that
    the same applies to enum strings and other non-trivial types.

To sum up: when I use compile-time constants, I usually take enum unless
those constants are arrays or I need a memory location for some other reason.

和我恋爱吧 2024-10-20 21:16:26

枚举总是在编译时初始化。因此,它们必须被赋予可以通过CTFE(编译时函数求值)创建的值。

不可变变量可以在运行时初始化。如果不可变变量具有全局生命周期(因此它是模块变量或静态类或静态局部变量),那么它必须在编译时或在运行时使用静态构造函数进行初始化(尽管静态局部变量不能被分配一个静态构造函数)。如果不可变变量是非静态局部变量,则它在运行时初始化(尽管如果该值是常量,则编译器可能会优化它并在编译时初始化它)。因此,与枚举不同,您可以在运行时创建不可变的局部变量。

编辑:我忘记的另一种情况:不可变成员变量必须直接使用 CTFE 初始化或使用不可变构造函数初始化。如果不可变成员变量直接使用 CTFE 初始化,那么显然这是在编译时完成的,而在不可变构造函数中初始化它是在运行时完成的。

enums are always initialized at compile time. So, they must be assigned values which can be created via CTFE (Compile Time Function Evaluation).

immutable variables can be initialized at runtime. If an immutable variable has a global lifetime (so it's a module variables or a static class or a static local variable), then it must be either be initialized at compile time or at runtime with a static constructor (though static local variables can't be assigned with a static constructor). If an immutable variable is a non-static local variable, then it's initialized at runtime (though if the value is a constant, then the compiler might optimize it and initialize it at compile time). So, you can create immutable local variables at runtime, unlike enums.

EDIT: One other case I forgot: immutable member variables must either be initialized directly with CTFE or initialized with an immutable constructor. If an immutable member varible is initialized directly with CTFE, then obviously that's done at compile time, whereas initializing it in an immutable constructor is done at runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文