天天看点

02序化构

​​原地址​​

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

static foreach(number; [1, 2, 3, 4, 5])
    {
writeln(number);
    }
}
//展开为:
void main()
{
import std.stdio : writeln;

writeln(1);
writeln(2);
writeln(3);
writeln(4);
writeln(5);
}
      

​static foreach​

​不会创建​

​域​

​,其在​

​编译时​

​如上展开.因而可能有问题,因此一般用​

​{{|}}​

​来配合​

​静每一​

​:

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

static foreach(number; [1, 2, 3])
    {{
int 复杂式 = number + number;
writeln(复杂式);
    }}
}
//展开为:
void main()
{
import std.stdio : writeln;

    {
int 复杂式 = 1 + 1;
writeln(复杂式);
    }

    {
int 复杂式 = 2 + 2;
writeln(复杂式);
    }

    {
int 复杂式 = 3 + 3;
writeln(复杂式);
    }
}
      

​别名​

​,可与​

​任意符号(如函数)​

​一起用,而不仅是​

​类型​

​.

struct SomeStruct
{
int a;
}

alias SStruct = SomeStruct;

void main()
{
// 只是别名.
SStruct a = SomeStruct(200);
}
      

​清单常量​

​:仅在​

​编译时​

​存在的​

​不变变量​

​.出现时,复制它.与​

​普通​

​变量一样,只是有​

​枚​

​前缀:

enum float PI = 3.14;
enum AGE = 200;
//可自动推导.
      

他们是​

​编译时​

​存储,且​

​静如​

​可访问的,因而​

​重要且有用​

​.注意:

enum MyArray = [1, 2, 3, 4];
//1,表示数组时,
static immutable MyArray = [1, 2, 3, 4];
//2,只表示1个时,这样就只复制一次,从而`s 是 t`.
void main()
{
auto s = MyArray;
auto t = MyArray;//1,会复制2次,
assert(s !is t);
}
      

​清单常量​

​可为​

​模板​

​.因而我们可实现自己的​

​特征​

enum myIsBoolean(T) = is(T == bool);
//可为模板.

enum isStringABoolean  = myIsBoolean!string; // 假
enum isBooleanABoolean = myIsBoolean!bool;   // 真

static assert(!isStringABoolean);
static assert(isBooleanABoolean);
      

有点类似​

​C++​

​的​

​概念​

​了.现在​

​序化构​

​,先检查是否是​

​原始类型​

enum isPrimitiveType(T) = isNumeric!T || is(T == bool) || is(T == string);
      

现在这样:

JSONValue serialise(T)(T value)
{
static if(isPrimitiveType!T)
    {
return JSONValue(value);
    }
else static if(is(T == struct))
    {
JSONValue toReturn;

// 用`的元组`来遍历成员.
static foreach(member; T.tupleof)
        {{
alias MemberType = typeof(member);
pragma(msg, MemberType.stringof);
        }}//{{}}来避免展开问题.

return toReturn;//
    }
}
      

先是​

​类型​

​,接着取​

​名字​

{{
alias MemberType = typeof(member);

// 编译器可推导为串.
const MemberName = __traits(identifier, member);
pragma(msg,MemberName~"是"~MemberType.stringof~"类型");
}}
      

用​

​插件​

​来将:

MemberType memberValue = mixin("value." ~ MemberName);
      

转为:

string memberValue = value.name;
int memberValue = value.age;
      

最后,​

​{{}}​

​中内容为:

{{
alias MemberType = typeof(member);
const MemberName = __traits(identifier, member);
MemberType memberValue = mixin("value." ~ MemberName);

// toReturn是个`数格`,用`成员名`为键,`成员值`为值.
toReturn[MemberName] = serialise(memberValue);
}}
      

​数格值​

​对象,就是个​

​统一对象​

​.所有类型均​

​归一​

​化为该类型.

void main()
{
import std.stdio;

// 用`动`指定类型
auto json = serialise(Person("Bradley", 20));
writeln(json);

/*
输出:
{"age":20,"name":"Bradley"}
*/
}
      

接着,​

​解序化​

​结构:

T deserialise(T)(JSONValue json)
{
/* 前面原始类型省略了*/
else static if(is(T == struct))
    {
T toReturn;//返回类型.

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

MemberType memberValue = deserialise!MemberType(json[MemberName]);
// 整个语句是`插件`,所以`插件`中也要有`分号`;
mixin("toReturn." ~ MemberName ~ " = memberValue;");
// 如:
// toReturn.name = memberValue;
// toReturn.age = memberValue;
        }}

return toReturn;
    }
/**/
}
      

测试:

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

auto json = serialise(Person("Bradley", 20));
writeln("数格: ", json);

auto person = deserialise!Person(json);
writeln("人: ", person);

/*
输出:
数格: {"age":20,"name":"Bradley"}
人: Person("Bradley", 20)
*/
}