Optional field in struct

Hi,
if I have defined a struct, e.g.

mutable struct A
    a::Tuple
end

and then saved an object of this struct with BSON

o = A((1,2))
BSON.@save "o.bson" o

is it then possible to add “optional” fields to the struct such that I can still load o.bson without an error? Because my struct has changed over time and I don’t want to always create a new struct with a new name. So e.g. the new struct could look something like this:

mutable struct A
    a::Tuple
    b::Bool
end

and BSON.@load "o.bson" o obviously results in an error. Whether the reloaded old object has the new field with some default value or doesn’t have the new field at all is irrelevant for my use case. I am thankful for any advice how to address this problem!

2 Likes

You cannot redefine type in Julia, this would make optimisation impossible, the compiler would need to dynamically check what is it dealing with all the time.

If you save data as one type and want to load is as something else, the best would be to make a explicit conversion. Renaming seems to be asking for trouble.

Have you looked at Parameters.jl?
It makes it easy define structs with optional keyword arguments, i.e. default values for fields that are not explicitly given.
For example b could default to false if no value is given.
I have not used BSON before, but the following example appears to work:

using BSON
mutable struct A
  a::Tuple
end
o = A((1, 2))
BSON.@save "o.bson" o

New session:

using Parameters
using BSON
@with_kw mutable struct A
  a::Tuple
  b::Bool = false
end
BSON.@load "o.bson" o
@assert o.a == (1, 2)
2 Likes

I am still learning, but in this case, a “nullable” type could be:
struct A
a::Union{Tuple,Nothing}
end

a1 = A((1,2,3))
a2 = A(nothing)

this can be saved in BSON too…

“Nullable” is most common in structs wiith many fields, like

struct Person
name::String
age::Union{Int64,Nothing}
end

in this case, must create two constructors:

Person(name)
Person(name, age)

age recieves nothing in first case

2 Likes