阿里d模板插件

帖子地址
作者:阿里.

string GenStruct(string Name, string M1) {
  return "struct " ~ Name ~ "{ int " ~ M1 ~ "; }";
}
unittest {
  mixin(GenStruct("Foo", "bar"));
  auto foo = Foo(42);
  assert(foo.bar == 42);
}

void main() {
}

你例子让人困惑,是由于包含与串插件无关元素.上面代码就没问题.

template GenStruct(string Name, string M1)
{
    const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }";
}

mixin(GenStruct!("Foo", "bar"));

上面的原始代码包含同名模板(a),a的意思是:模板定义中有与模板同名的符号定义,则该符号与模板实例意思一样.GenStruct!("Foo", "bar")与模板的GenStruct成员一样.
在模板中创建多个常 符[].模板可利用其实现中的其他符号.

template GenStruct(string Name, string M1)
{
  //注意,下面两个都可定义为`枚`
  //只是为了保持风格一致
  const char[] memberDef = "int " ~ M1 ~ ";";
  const char[] GenStruct = "struct " ~ Name ~ "{ " ~ memberDef ~ " }";
}

这样用:

//定义两符号
template Foo(string s) {
  import std.format : format;

  enum integerVarDef=format!"int %s_i;"(s);
  enum doubleVarDef=format!"double %s_d;"(s);
}

// 插入一个符号
void main() {
  mixin(Foo!"hello".integerVarDef);
  hello_i = 42;

  mixin(Foo!"world".doubleVarDef);
  world_d = 1.5;
}

一起插件,注意,这是模板插件不是串插件.

template MemberListFeature(T)  {
  T[] theList;

  void addMember(T value) {
    theList ~= value;
  }

  T getMember(size_t index) {
    return theList[index];
  }
}

struct S {
  mixin MemberListFeature!string;
  //现在该结构有一个成员数组及两个成员函数
}

unittest {
  auto s = S();
  s.addMember("hello");
  s.getMember(0) == "hello";
}

void main() {
}

可在编译时用foreach,但不能在模板域中用.但可编译时在模板域/模块域中用static foreach.
可这样实现你的意思:

template Vector(int dimension) {
  import std.conv : to;

  string makeMembers() {
    string cps;
    foreach(d; 0..dimension) {
      // D中不必用初值,因为已初化了.
      cps ~= "int x" ~ d.to!string ~ ";\n";
    }
    return cps;
  }

  //向量困惑,改为`向量构`
  const char[] Vector = "struct VectorStruct {\n"
                        ~ makeMembers()
                        ~ "}";
}

//可视化结果
pragma(msg, Vector!5);
//或用编译器开关`-mixin`来可视化.

mixin(Vector!3);

void main() {
  auto v = VectorStruct();
  v.x0 = 0;
  v.x1 = 1;
  v.x2 = 2;
}

静每一来实现:

struct Vector(size_t dimension) {
  static foreach (d; 0..dimension) {
    import std.format : format;
    mixin (format!"  int x%s;"(d));
  }
}

void main() {
  auto v = Vector!3();
  v.x0 = 0;
  v.x1 = 1;
  v.x2 = 2;
}

最后问题,你可这样:

struct Vector(size_t dimension) {
  static foreach (d; 0..dimension) {
    import std.format : format;
    mixin (format!"  int x%s;"(d));
  }
}

import std.stdio;

void main() {
  auto a = Vector!2(1, 2);
  auto b = Vector!2(3, 4);
  auto c = add(a, b);

  writeln(c);
}

Vector!dim add(size_t dim)(Vector!dim lhs, Vector!dim rhs) {
  return Vector!dim(lhs.x0 + rhs.x0);
    //假定只有x0成员的实现
}

如何迭代?
可用.tupleof,也可用int[dimension]静态数组.类似这样:

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