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)
*/
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现