Avoiding repeated type declaration

I find myself repeating a somewhat cumbersome type declaration, which seems like something to avoid. How? Here’s a condensed version of my current code, which uses Vector{Union{Missing, IntervalBox{1, Float64}}} twice.

"enumerate desired calculation for WorkArea"
# implicit value assignment starts at 0.  But I want to use these as array indices
# and julia arrays are 1-based.
@enum Objective justZ=1 justW=2 WZ=3 just1=4

"""
Working data for a particular thread.
"""
mutable struct  WorkArea{TEvaluator,TSegs}
    # ... many fields omitted
    "record details of the integration.  Int(Objective) has result for that Objective"
    intervals::Vector{Union{Missing, IntervalBox{1, Float64}}}
end

"convenient constructor"
function WorkArea(dat::DataFrame, ev::TEvaluator) where {TEvaluator}
    zip::UInt = 0
    WorkArea(dat, dat.Y, ev, work(ev), WZ, zip, zip, zip, Vector{Union{Missing, IntervalBox{1, Float64}}}(missing, 4))
end

I think the type in the constructor is mandatory to get the correct type; I could omit it from the struct definition, with perhaps some loss of efficiency.

I looked for something that would give me the type of a component of a struct, something like typeof(Workarea.intervals), but didn’t find it.

You could just declare a type constant.

const IntervalBoxVector = Vector{Union{Missing, IntervalBox{1, Float64}}}

There is also a way to query the type of a field.

julia> struct Foo
           a::Int
           b::Float64
           c::Vector{Union{Missing, Float64}}
       end

julia> fieldtype(Foo, :c)
Vector{Union{Missing, Float64}} (alias for Array{Union{Missing, Float64}, 1})
4 Likes

Perfect! Thanks very much.

I was surprised to find that fieldtype() can even be used where a type would go, e.g.,

struct foo; i::Int; end
struct foo2; j::fieldtype(foo, :i); end

Seems to work to give j type Int64.

3 Likes