d的类型元组
import std.typetuple;
alias list = TypeTuple!(AA, AB, AC);
但是,不能在运行时
像数组一样索引它;尝试newlist[n]
将是编译时错误.相反,创建辅助
函数来循环
它并返回实例,如下所示:
foreach(index, type; list)
if(index == testv) {
a = new type();
break;
}
展开
foreach(foo; compile_time_list)
就像:
if(0 == testv) { a = new AA(); goto end; }
if(1 == testv) { a = new AB(); goto end; }
if(2 == testv) { a = new AC(); goto end; }
end:
因此,适用于运行时值
,帮助绑定编译时列表
和数组索引
.
注意,并非最有效,另一个提高速度
选择是在编译时
从列表中生成switch
语句,然后插件
它.将编译switch
语句为更有效
的查找表
.但也许简单
循环也很好.
无论如何,把它放在一起,得到:
import std.stdio;
interface A {}
class AA: A {}
class AB: A {}
class AC: A {}
import std.typetuple;
alias list = TypeTuple!(AA, AB, AC);
void testf(ulong testv) {
A a;
foreach(index, type; list)
if(index == testv) {
a = new type();
break;
}
if(a is null)
writeln("坏索引");
else {
writeln("创建了",typeid(cast(Object) a));
}
}
void main() {
testf(0);
testf(1);
testf(2);
testf(3);
}
//结果
$ ./test50
创建了test50.AA
创建了test50.AB
创建了test50.AC
坏索引
typeid(cast(Object)a)
可能看起来很奇怪,那是获取类型的动态类
.它必须首先转换为Object
,否则它将打印接口名称
.由于D接口
不一定是D类
(它们也可以是COM
对象或C++
类),因此typeid
并不总是可用的.转换为Object
确保它是D类
,从而获取运行时
类型的详细信息
.
检查循环中的基类
可以为它编写自己的元组模板
,或者只是让工厂函数
上的编译失败:A a=new T();
如果A不是T的基类
或接口
,则会失败.
bool checkClassList(Base, T...)() {
foreach(t; T) {
static if(!is(t : Base))
static assert(0, t.stringof ~ "不是..的子类" ~ Base.stringof);
}
return true;
}
template ClassList(Base, T...) if(checkClassList!(Base, T)) {
alias ClassList = T;
}
用法:
alias list = ClassList!(A, AA, AB, AC);
//正确
class B {}
alias list = ClassList!(A, AA, AB, AC, B);
//错误.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现