Keeping a "reference" to a struct field

There is a PR for that, but it’s not possible out of the box right now. You might be able to roll your own, e.g. copying the relevant bits from this PR:

import Base: RefValue, getindex, setindex!, isassigned, fieldindex

struct RefField{f,T,S} <: Ref{T}
    x::RefValue{S}
    RefField{f,T,S}(x::S) where {f,T,S} = new{f::Int,T,S}(RefValue(x))
end

RefField(x, f::Int) = RefField{f, fieldtype(typeof(x), f), typeof(x)}(x)
RefField(x, f::Symbol) = RefField(x, fieldindex(typeof(x), f))

getindex(b::RefField{f}) where {f} = getfield(b.x[], f)
setindex!(b::RefField{f,T}, x) where {f,T} = (setfield!(b.x[], f, convert(T, x)); b)
isassigned(b::RefField{f}) where {f} = isdefined(b.x[], f)

mutable struct T
    a::Int
end

t = T(1)
x = RefField(t, :a)
t.a = 2
@show x[] # 2

Maybe a package doing this already exists?

2 Likes