序列化
sric通过内建的动态反射来支持序列化,序列化格式为文本格式HiML。
序列化例子
要序列化的类需要reflect标记。例如:
reflect struct Point {
var x: Int
var y: Float
}
unsafe fun testSimple() {
var encoder: Encoder;
var obj = new Point { .x = 1; .y = 2 }
var t = obj as *Void;
var res = encoder.encode(t, "testSerial::Point")
printf("%s\n", res.c_str())
var decoder: Decoder
var p = decoder.decode(res)
var obj2: raw* Point = unsafeCast$<raw*Point>(p)
verify(obj2.x == obj.x)
verify(obj2.y == obj.y)
}
上面的例子中由于Point是非多态对象,所以要显式传入名称"testSerial::Point"。
避免序列化
有时候有些字段不想序列化,可以用Transient注解来标记
reflect struct Point {
var x: Int
//@Transient
var y: Float
}
如果本身不想序列化,可以通过_isTransient方法来动态决定
reflect struct Point {
var x: Int
fun _isTransient(): Bool {
return false
}
}
反序列化后处理
有时候希望反序列化后,调用指定函数来恢复状态。名称为_onDeserialize的函数将被自动调用。
reflect struct Point {
var x: Int
fun _onDeserialize() {
}
}
简单模式序列化
正常情况下自定义类被序列化为HiML对象,可通过SimpleSerial注解将其序列化为字符串。例如我们想要把Insets序列化为"1 2 3 4"而不是"Insets{top=1,right=2,bottom=3,left=4}"
//@SimpleSerial
reflect struct Insets {
var top: Int = 0
var right: Int = 0
var bottom: Int = 0
var left: Int = 0
fun toString() : String {
return String::format("%d %d %d %d", top, right, bottom, left)
}
fun fromString(str: String): Bool {
var fs = str.split(" ")
if (fs.size() == 4) {
top = fs[0].toInt32()
right = fs[1].toInt32()
bottom = fs[2].toInt32()
left = fs[3].toInt32()
return true
}
return false
}
}
序列化和反序列化过程中会自动调用toString和fromString,两个函数的签名必须和上面完全一致。