After digging into the implementation of serialization/deserialization in my current version of Julia (0.6.2), I found a solution. Here is the solution that worked for the example in the question:
# 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
Now, if you run the test code again:
# 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
The test code outputs:
foo1 = Foo(1, 2)
foo2 = Foo(1, nothing)
I should mention that the above solution depends on the current implementation of serialization/deserialization (in Julia 0.6.2) and there's no guarantee about its stability in the future. Hence, I'll still keep an eye on finding a better solution.
Update: The above code does not work after Julia 1.0. Here is the updated code:
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