原位址
序化枚舉
,先要考慮是序化 值/名字
.我們按 名
序化, 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)
*/
}
類
與
構
不一樣:
| 與 不同的特點 |
| 類可為 . |
| 不能可靠建構 |
| 不能直接暴露 變量,等等 |
類/構
一起:
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)
*/
}