​插件模板​​自动生成​​样板​​代码,并​​复制粘贴​​进​​插件​​语句处.它是​​全功能​​的,可以用​​静如​​及​​串插件​​.我们来试试​​自动​​生成​​解序化​​函数.

class PersonClass
{
private
{
string name;
int age;
PersonType type;
}

this()
{
}

this(string name, int age, PersonType type)
{
this.name = name;
this.age = age;
this.type = type;
}

override string toString()
{
import std.format : format;
return "我是%s,%s岁,是个%s.".format(this.name, this.age, this.type);
}
}

创建插件模板

该​​插件模板​​叫​​AutoStaticDeserialise(自动静解序化)​​.

mixin template AutoStaticDeserialise()
{
}
//可在`括号`中定义`模板参数`.

使用方法:

class PersonClass
{
mixin AutoStaticDeserialise;
//省略...
}

测试​​有意思​​的​​插件模板​​性质:

mixin template AutoStaticDeserialise()
{
private alias ThisType = typeof(this);
pragma(msg, ThisType);
}

class PersonClass
{
mixin AutoStaticDeserialise;

private
{
string name;
//省略
}
// 略...
}

/*
输出:
PersonClass
*/

​插件模板​​是​​复制粘贴​​进去的.我们甚至可访问​​被插件​​里面的​​私有​​成员.当作​​C++​​的​​宏​​就差不多了.

加编译时检查

我们的​​解序化​​仅适用​​类​​,且要求​​默认构造函数​​.我们加些​​静断​​.

mixin template AutoStaticDeserialise()
{
private alias ThisType = typeof(this);
static assert(is(ThisType == class), "仅对类");
static assert(HasDefaultCtor!ThisType, "要求有默认构造函数");
}

完整版:

mixin template AutoStaticDeserialise()
{
...//前三行如上,略
public static ThisType deserialise(JSONValue json)
{
if(json.type == JSONType.null_)
{//无效类
return null;
}

auto instance = new ThisType();//实例

static foreach(member; ThisType.tupleof)
{{
alias MemberType = typeof(member);
const MemberName = __traits(identifier, member);

MemberType memberValue = json[MemberName].deserialise!MemberType();
mixin("instance." ~ MemberName ~ " = memberValue;");
}}//静态解序化.

return instance;
}
}

测试:

void main()
{
import std.stdio : writeln;

auto person = new PersonClass("Bradley", 21, PersonType.Student);
writeln(deserialise!PersonClass(parseJSON(`{ "name": "Bradley", "age": 21, "type": "Student" }`)));
}

/*
输出:
我是Bradley,21岁,我是Student.
*/