Is accessing the fields of a struct a good julia-style?

Julia lets you define accessors later, e.g. if you rename the fields, you can still provide old names using getproperty():

struct Foo{T}
  new_data::Vector{T}
  new_ptrs::Vector{Int}
end

function Base.getproperty(foo::Foo, p::Symbol)
    if p == :data
        return getfield(foo, :new_data)   # getfield() reads fields directly and it cannot be overloaded
    elseif p == :ptrs
        return getfield(foo, :new_ptrs)
    else
        return getfield(foo, p)
    end
end

f = Foo([1,2,2,5,1,7],[1,3,6,7])
println(f.data)
println(f.ptrs)

Note that Julia compiler is smart enough to still translate simple getproperty() calls into direct field pointers:

julia> using BenchmarkTools

julia> @btime $f.data;
  1.753 ns (0 allocations: 0 bytes)

julia> @btime $f.new_data;
  1.754 ns (0 allocations: 0 bytes)

There’s also Base.setproperty!() for property mutation.

2 Likes