奇异模板加编译时自省加静态构造是成功,以自动序化,解序为例
原文地址
作者:h.s.teoh
最近,我需要扩展简单序化
系统,来处理多态
对象.
昨天,我发现个优秀解决方案:用crtp(奇异递归模板)
,来注入方法至继承
类.
class Saveable(Derived, Base) : Base {
static if (is(Base == Object)) {//基类
// 顶级虚函数
void save() { ... }
} else {
//继承类,盖
override void save() { ... }
}
}
class Base : Saveable!(Base, Object) { ... }
class Derived1 : Saveable!(Derived1, Base) { ... }
class Derived2 : Saveable!(Derived1, Base) { ... }
奇异声明
在类的第1行
,很难丢失.可保存
的基
参数,使我们容易注入
盖方法至类层次
,并区别基类/继承类
.
可保存
的保存
方法,用模板
参数来自省
继承类并生成序化
字段代码.在序化输出中它包含生成标识类型的标签的代码
.从而完成了一半序化.
为了解序
,可以用对象.工厂
.但接口
太旧,且从正确类型
中读回字段有断开,因而可以用静态构造器
来修复.
alias Loader = Object function(InputFile);
Loader[string] classLoaders;
class Saveable(Derived, Base) : Base {
static if (is(Base == Object)) {//基类
// 顶级虚函数
void save() { ... }
} else {
//继承类,盖
override void save() { ... }
}
static this()//静态构造器.
{
classLoaders[Derived.stringof] = (InputFile f) {
auto result = new Derived;
... //用自省来读回继承的字段
return result;
};
}
}
这儿神奇的地方是,每个可保存
的实例生成一个静 本()
块,有继承类
的全部编译时信息
.所以函数字面
可用编译时
自省来生成可序化
代码.然后通过以类名
作为键
来注册函数字面
进全局加载表
.(为了简单
,这里我用.的串
,对大规模项目,你可用.的混杂
).
因为,静 本
块在启动程序,加载动态库
时运行.确保启动程序
后类加载器
有程序要用的所有信息
.所以解序代码
可简单在类加载器
中查找保存的类型签
.并调用函数指针
来重构
对象.结果是,为可序化
任何类,你只需要用:
class MyClass : Saveable!(MyClass, MyBase) { ... }
替换:
class MyClass : MyBase { ... }
其他所有全部自动搞好.不需要插件,重复序化类,运行时类型信息
,甚至还支持动态库加载的类定义
.只要你用Runtime.loadLibrary
来确保运行静态构造器
.因为静态构造器
会注入
任何新类加载器至类加载器
.并自动教会解序代码
如何解序
.
奇异模板+编译时自省+静态构造==成功
!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现