怎么做!string(enum.member)有效吗?

时间:2014-07-08 01:47:44

标签: d dmd

std.conv.to!string(enum.member)如何运作?一个函数如何获取枚举成员并返回其名称?它是使用编译器扩展还是类似的东西?自从我来自C / C ++世界以来,这对我来说有点平常。

1 个答案:

答案 0 :(得分:9)

它的作用是使用枚举类型的编译时反射来获取成员列表(名称作为字符串)及其值。它根据此信息构造一个switch语句,以便快速查找以从值中获取名称。 to!SomeEnum("a_string")使用相同的原则,只是在另一个方向。

使用__traits(allMembers, TheEnumType)访问编译时反射信息,它返回一个字符串列表,可以循环以构建switch语句。然后__traits(getMember, TheEnumType, memberName)用于获取正文。

此处可以看到更多特征:http://dlang.org/traits.html#allMembers

那个allMembers可以处理许多类型,不仅仅是示例中看到的类,还有结构,枚举等,甚至是模块。

phobos源代码包含EnumMembers std.traits__traits(allMembers)的一些示例:https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L3360

尽管phobos源有点难以阅读,但在第3399行,在该函数的底部,您可以使用std.conv.to作为其数据源来查看它。 std.traits是根据许多case函数实现的。

您还可以查看示例章节标签,从我的D食谱中获取反思章节,该章节也讨论了这些内容:

http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book

该章的最后一个例子展示了如何使用几种反射功能来构建一个基于字符串的小函数调度程序。以下章节(虽然不是免费提供)展示了如何构建一个开关以提高效率。这实际上非常简单:只需将foreach语句放在{{1}}内的编译时数据上,D编译器就会展开,然后为你优化查找表!