Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Enums 具有基类型异常行为的D lang枚举_Enums_D - Fatal编程技术网

Enums 具有基类型异常行为的D lang枚举

Enums 具有基类型异常行为的D lang枚举,enums,d,Enums,D,我涉猎了D,并对指定基类型的命名枚举与匿名枚举的行为感到惊讶。给定以下D代码: 导入标准stdio; 枚举strs:字符串 { Foo=“你好”, Bar=“世界”, } 枚举:字符串 { anon1=“笔”, anon2=“剑”, } int main(字符串[]args) { writefln(“%s%s”,strs.Foo,strs.Bar); writefln(“%s%s”,anon1,anon2); 返回0; } 这将产生: Foo Bar pen sword 换句话说,对于命名枚

我涉猎了D,并对指定基类型的命名枚举与匿名枚举的行为感到惊讶。给定以下D代码:

导入标准stdio;
枚举strs:字符串
{
Foo=“你好”,
Bar=“世界”,
}
枚举:字符串
{
anon1=“笔”,
anon2=“剑”,
}
int main(字符串[]args)
{
writefln(“%s%s”,strs.Foo,strs.Bar);
writefln(“%s%s”,anon1,anon2);
返回0;
}
这将产生:

Foo Bar
pen sword
换句话说,对于命名枚举,将值作为字符串传递给writefln将打印值的名称,而不是值本身。但对于匿名枚举,执行相同的操作会打印值本身

这似乎是一种奇怪的矛盾。为什么会这样


我使用的是Visual D 0.3.42。

无名枚举只是一个清单常量块,没有自己的类型。意思是:

enum:string
{
anon1=“笔”,
anon2=“剑”,
}
…与…相同

枚举字符串anon1=“pen”; 枚举字符串anon2=“剑”;
然而,您的
strs
enum本身就是一种类型,因此
writefln
打印出enum字段名(无论多么奇怪)。

好吧,部分问题在于关键字
enum
在D中被过度使用。匿名枚举有时被称为清单常量。宣布

enum:string
{
anon1=“笔”,
anon2=“剑”,
}
基本上与

枚举字符串anon1=“pen”; 枚举字符串anon2=“剑”; 或

enum anon1=“pen”;
enum anon2=“剑”;
因为它们将被推断为
字符串
。这些真的不是枚举。只是在一个块中声明它们,而不是单独声明。它们更像是#在C中定义一个常量,因为你声明了一个没有地址的符号,它将被替换为在任何使用该符号的地方分配的值。它不像
enum
通常所认为的那样是一个关联值列表。事实上,这些断言将失败:

assert(is(typeof(anon1)==enum));
断言(is(typeof(anon2)==enum));
这是因为它们是显式常量,而不是传统意义上的枚举。与之相比

assert(is(typeof(strs.Foo)==enum));
断言(is(typeof(strs.Bar)==enum));
这将通过-因为
strs
是一个实际的
enum
而不是清单常量(尽管枚举与清单常量相似,因为它们没有地址,当您使用它们时,它们只是被它们的值替换-这可能是清单常量也使用
enum
关键字的部分原因)

因此,从
writefln
的角度来看,
anon1
anon2
只是字符串,它会像任何字符串一样打印它们,而
Foo
Bar
是枚举,所以它会打印它们的名称。在内部,
writefln
使用
is(T==enum)
来检查某个东西是否是
enum
,就像那些断言一样,只有那些是实际的enum而不是manifest常量的断言才会导致该表达式为true,因此它们才是打印名称的断言