It is pretty customary to represent an optional never-nothing field by Union{Nothing, Typ}
, while representing partial data (e.g. unfetched data) as Union{Missing, Typ}
. For optional fields that can be nothing, a common idiom is Maybe{Typ}
. The third customary way of representing non-present data is by sentinel values. The built-in sentinel value for gc-managed types is nullpointer.
However, nullpointer is not officially encouraged for this purpose and pretty annoying, because it only works for gc-controlled types (not for bitstypes), which leaks abstractions and can break on upgrades, and you need to check isassigned
before access, and you need to manipulate pointers to “unassign” a field or array entry. Nevertheless, nullpointer is the most performant way and is emitted by inner constructors that don’t set all fields, as well as Array{T,N}(undef, sz)
. An alternative to nullpointers is to use an explicit sentinel value like const _nil = Typ(args...)
and then check if foo.bar === _nil
(you want triple equality here).
Given these customs, the answer would be missing
or a more specific type like struct FetchError code::Int32 end
that encodes information about the error (e.g. network error, parsing error, successfully fetched and parsed but pruned at later times).