如何在Julia中为结构实现自定义序列化/反序列化?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Julia中为结构实现自定义序列化/反序列化?相关的知识,希望对你有一定的参考价值。

Base.serializeBase.deserialize的默认实现为整个给定对象执行序列化/反序列化。

排除字段序列化并仍能正确反序列化的正确方法是什么?

这是一个简化的代码示例:

# The target struct
struct Foo
    x::Int
    y::Union{Int, Void} #we do not want to serialize this field
end

foo1 = Foo(1,2)

# Serialization
write_iob = IOBuffer()
serialize(write_iob, foo1)
seekstart(write_iob)
content = read(write_iob)

# Deserialization
read_iob = IOBuffer(content)
foo2 = deserialize(read_iob)

@show foo1
@show foo2

上面代码的输出是:

foo1 = Foo(1, 2)
foo2 = Foo(1, 2)

并且期望的结果应该是:

foo1 = Foo(1, 2)
foo2 = Foo(1, nothing)

在这里,我假设我们可以为缺失的字段定义一个默认值,例如nothingyin上面的输出。

答案

在我当前版本的Julia(0.6.2)中深入研究序列化/反序列化的实现之后,我找到了一个解决方案。以下是问题中示例的解决方案:

# Custom Serialization of a Foo instance
function Base.Serializer.serialize(s::AbstractSerializer, instance::Foo)
    Base.Serializer.writetag(s.io, Base.Serializer.OBJECT_TAG)
    Base.Serializer.serialize(s, Foo)
    Base.Serializer.serialize(s, instance.x)
end

# Custom Deserialization of a Foo instance
function Base.Serializer.deserialize(s::AbstractSerializer, ::Type{Foo})
    x = Base.Serializer.deserialize(s)
    Foo(x,nothing)
end

现在,如果再次运行测试代码:

# The target struct
struct Foo
    x::Int
    y::Union{Int, Void} #we do not want to serialize this field
end

foo1 = Foo(1,2)

# Serialization
write_iob = IOBuffer()
serialize(write_iob, foo1)
seekstart(write_iob)
content = read(write_iob)

# Deserialization
read_iob = IOBuffer(content)
foo2 = deserialize(read_iob)

@show foo1
@show foo2

测试代码输出:

foo1 = Foo(1, 2)
foo2 = Foo(1, nothing)

我应该提一下,上面的解决方案取决于序列化/反序列化的当前实现(在Julia 0.6.2中),并且不能保证其未来的稳定性。因此,我仍然会留意寻找更好的解决方案。

以上是关于如何在Julia中为结构实现自定义序列化/反序列化?的主要内容,如果未能解决你的问题,请参考以下文章

如何将多个键值条目的 JSON 对象反序列化为 Rust 中的自定义结构

我们如何在 Hive 中为自定义 Writable 类型编写自定义 ObjectInspector?

如何在 ASP.NET Web API 中为 Json.NET 设置自定义 JsonSerializerSettings?

如何使用 Json.Net 序列化/反序列化具有附加属性的自定义集合

guid的值为null如何在C#反序列化

如何为计时时间戳使用自定义 serde 反序列化器?