簡體   English   中英

如何在 Julia 中為結構實現自定義序列化/反序列化?

[英]How to implement custom serialization/deserialization for a struct in 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)

在這里,我假設我們可以為缺失的字段定義一個默認值,例如,上面輸出中的y nothing

在深入研究了我當前版本的 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 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM