🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
许多运行时值可以被序列化或反序列化,使用 haxe.Serializer 和 haxe.Unserializer 类。都支持两种用法: 创建一个实例,并不断的调用 serialize / unserialize 方法来处理多个值。 调用它们的静态 run 方法来 序列化/反序列化 一个单独的值。 下面的例子演示了第一种用法: ~~~ import haxe.Serializer; import haxe.Unserializer; class Main { static function main() { var serializer = new Serializer(); serializer.serialize("foo"); serializer.serialize(12); var s = serializer.toString(); trace(s); // y3:fooi12 var unserializer = new Unserializer(s); trace(unserializer.unserialize()); // foo trace(unserializer.unserialize()); // 12 } } ~~~ 序列化的结果(这里存储在局部变量 s)是一个 String,并且可以被任意甚至远程地传递。它的格式以 序列化格式(第10.8.1节)描述。 ## 支持的值 * null * Bool, Int 和 Float (包括无穷值和 NaN) * String * Date * haxe.io.Bytes (编码为 base64) * Array 和 List * haxe.ds.StringMap, haxe.ds.IntMap 和 haxe.ds.ObjectMap * 匿名结构 * Haxe 类实例(并不是原生的) * 枚举实例 ## 序列化配置 序列化可以以两种方式配置。对于一个静态变量,可以被设置来改变所有 haxe.Serializer 实例,一个成员变量可以被设置来影响一个特定实例: * USE_CACHE,userCache : 如果为 true,重复的结构或类/枚举实例被参照序列化。这可以避免递归数据的无限循环更长的序列化时间。默认,对象缓存是禁用的;然而字符串总是被缓存。 * USE_ENUM_INDEX,useEnumIndex : 如果为 true ,枚举构造函数被它们的索引序列化而不是它们的名字。这可以使结果字符串更短,但是如果 枚举构造函数在反序列化之前被插入到这个类型,将会打断。这个行为默认是禁止的。 ## 反序列化行为 如果序列化结果被存储,之后使用于反序列化,必须注意当使用类和枚举实例时要保持兼容性。之后重要的是准确理解反序列化如何实现的。 * 做反序列化的地方类型必须在运行时可以获得的。如果无用代码消除被激活,只是通过序列化使用的类型可能会被删除。 * 每个 Unserializer 都有一个成员变量 resolver ,用于通过名字解析类和枚举。Unserializer 一经创建,它被设置为 Unserializer.DEFAULT_RESOLVER 。它和实例成员都可以被设置为一个定制 分析器。 * 类使用 resolver.resolveClass(name) 通过名字解析。实例然后被使用 Type.createEmptyInstance 创建,这意味着 这个类构造函数没有被调用。最终,实例字段根据序列化的值被设置。 * 枚举使用 resolver.resolveEnum(name)通过名字及诶系。枚举实例然后被使用 Type.createEnum创建,如果可用,则使用序列化的参数值。如果构造函数参数由于序列化被改变,结果是未指定的。 ## 自定义的(反)序列化 如果一个类定义了成员方法 hxSerialize,这个方法被序列化器调用,允许对类的自定义序列化。同样,如果一个类定义了成员方法 hxUnserialize,它被反序列化器调用: ~~~ import haxe.Serializer; import haxe.Unserializer; class Main { var x:Int; var y:Int; static function main() { var s = Serializer.run(new Main(1, 2)); var c:Main = Unserializer.run(s); trace(c.x); // 1 trace(c.y); // -1 } function new(x, y) { this.x = x; this.y = y; } @:keep function hxSerialize(s:Serializer) { s.serialize(x); } @:keep function hxUnserialize(u:Unserializer) { x = u.unserialize(); y = -1; } } ~~~ 在这个例子中,我们决定要忽略成员变量 y的值,并且不序列化它。相反,我们在 hxUnserialize中默认它为 -1 。两个方法都使用 @:keep 元数据注解,以防止无用代码消除删除它们,因为它们在代码中从未恰当的引用。 查看 Serializer 和 Unserializer API 文档了解详细内容。