03序化枚举和类
原地址
序化枚举,先要考虑是序化值/名字.我们按名序化,
enum PersonType
{
Unknown,
Student,
Staff
}
struct Person
{
string name;
int age;
PersonType type;
}
按值类型检查,则是
is(PersonType==int)
//或
isNumeric!PersonType
按名则是,
is(T == enum)
原始类型中,我们可忽略枚举
enum isPrimitiveType(T) = !is(T == enum) && (isNumeric!T || is(T == bool) || is(T == string));
//第1个判断式.
JSONValue serialise(T)(T value)
{
static if(isPrimitiveType!T)
{ /* ... */ }
else static if(is(T == enum))
{
return JSONValue(value.to!string());
// PersonType.Student -> "Student", PersonType.Staff -> "Staff", etc.
}//值转串.
...
}
反序化:
T deserialise(T)(JSONValue json)
{
static if(is(T == enum))
{//放第1个
// "Student"->PersonType.Student,etc.
return json.str.to!T();
}
...
}
测试:
void main()
{
import std.stdio : writeln;
auto json = serialise(PersonType.Student);
writeln(json);
writeln(json.deserialise!PersonType());
json = serialise(Person("Bradley", 20, PersonType.Student));
writeln(json);
writeln(json.deserialise!Person());
/*
输出:
"Student"
Student
{"age":20,"name":"Bradley","type":"Student"}
Person("Bradley", 20, Student)
*/
}
类与构不一样:
序号 | 与构不同的特点 |
|---|---|
1 | 类可为无效. |
2 | 不能可靠构建类 |
3 | 不能直接暴露类变量,等等 |
类/构一起:
else static if(is(T == struct) || is(T == class)) //记得检查类.
{
JSONValue toReturn;
static if(is(T == class))
{
if(value is null)
{
return JSONValue(null);
}//处理空类.
}
else
{
T toReturn; // 类默认为`无效`,我们不能重用这句
}
static foreach(member; T.tupleof)
{{
/**/
}}
return toReturn;
}
简单测试:
void main()
{
import std.stdio : writeln, writefln;
auto p = new Person();
p.name = "Bradley";
p.age = 20;
p.type = PersonType.Student;
auto json = p.serialise();
writeln(json);
// writeln不像构一样自动格式化类
//或者重载`toString`,或者手写.
writefln("Person(%s, %s, %s)", p.name, p.age, p.type);
/*
输出:
{"age":20,"name":"Bradley","type":"Student"}
Person(Bradley, 20, Student)
*/
}
然后是,解序化:
T deserialise(T)(JSONValue json)
{
...
else static if(is(T == struct) || is(T == class)) //记得检查类
{
static if(is(T == class))
{
if(json.type == JSONType.null_)
return null;//无效类型
T toReturn = new T();
}
else
{
T toReturn;
}
/**/
return toReturn;
}
else
{ /*略*/ }
}
测试空类.
void main()
{
import std.stdio : writeln;
Person p = null;
auto json = p.serialise();
writeln(json);
writeln(json.deserialise!Person());
/*
输出:
无效
无效
*/
}
当前用new T()构建类,仅在无构造器/有默认构造器时管用.而实际中,类可有参数化构造函数,且不支持默认构造函数.加上:
enum HasDefaultCtor(T) = __traits(compiles, new T());
判断,是否有默认构造器.构造函数问题的变通,事实类一般不公开变量.
enum HasStaticDeserialiseFunc(T) = __traits(compiles, { T obj = T.deserialise(JSONValue()); });
//要检查代码在`括号`内.
T.deserialise解序化为静态函数.返回给T,检查是否兼容T,以数格值为第1参数.
现在,解序化是这样的:
enum HasStaticDeserialiseFunc(T) = __traits(compiles, { T obj = T.deserialise(JSONValue()); });
T deserialise(T)(JSONValue json)
{
...
/**/
else static if(is(T == struct) || is(T == class))
{
static if(is(T == class))
{
static assert(HasDefaultCtor!T || HasStaticDeserialiseFunc!T,
"class `" ~ T.stringof ~ "`要求默认构造器或匹配静的" ~ T.stringof ~ " deserialise(JSONValue)`"
); //条件.用`静态反序化`反序化
static if(HasDefaultCtor!T)
{
T toReturn = new T();
}//有默认构造
}
/**/
return toReturn;
}
else
{ /**/ }
}
外面:
//解序化/反序化
else static if(is(T == struct) || is(T == class))
{
static if(is(T == class))
{ /* 前面,处理无效 */ }
else
{ /**/ }//类的无效
static if(HasStaticDeserialiseFunc!T)
{
return T.deserialise(json);
}//类可`解序化`.
else //
{
static foreach(/**/)
{{
/**/
}}
return toReturn;
}
}
测试:
class Person
{
private
{
string name;
int age;
PersonType type;
}
// 无默认构造器
this(string name, int age, PersonType type)
{
this.name = name;
this.age = age;
this.type = type;
}
static Person deserialise(JSONValue value)
{
// 必须自己实现`解序化`
return new Person(
value["name"].deserialise!string(),
value["age"].deserialise!int(),
value["type"].deserialise!PersonType()
);
}
// 显示信息
override string toString()
{
import std.format : format;
return format("Person(%s, %s, %s)", this.name, this.age, this.type);
}
}
void main()
{
import std.stdio : writeln;
auto person = new Person("Bradley", 20, PersonType.Student);
auto json = person.serialise();
writeln(json);
person = json.deserialise!Person();
writeln(person);
/*
输出:
{"age":20,"name":"Bradley","type":"Student"}
Person(Bradley, 20, Student)
*/
}
浙公网安备 33010602011771号