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);
//错误.
posted @   zjh6  阅读(20)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示