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

标签 serialization deserialization 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)

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

最佳答案

在深入研究了我当前版本的 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 中),并且不能保证其 future 的稳定性。因此,我会继续关注寻找更好的解决方案。


更新:上述代码在 Julia 1.0 之后不起作用。这是更新后的代码:

using Serialization

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

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

# Custom Deserialization of a Foo instance
function Serialization.deserialize(s::AbstractSerializer, ::Type{Foo})
    x = Serialization.deserialize(s)
    Foo(x,nothing)
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

关于serialization - 如何在 Julia 中为结构实现自定义序列化/反序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49007433/

相关文章:

java - 序列化和反序列化同一对象并不反射(reflect)其状态的变化

java - 二进制数据的未知编码/序列化

multithreading - Julia `remotecall`线程给出不同的结果

julia - 在 Julia 中创建任意大小的 `nothing` 数组

java - Jackson @JsonView 注释会干扰可见性

c# - 将嵌套的 XML 元素反序列化为 C# 中的类

java - 如何更好地调试Java中的空指针异常

julia - 使用 Plots.jl 的色阶

json - 我如何确保 SerializeJSON 保留尾随/前导零?

java - 如何在 Web 服务中序列化公共(public)静态最终字符串?