Is there a package which makes it convenient to get a copy of an (immutable) struct with new values for some fields? I am aware of Setfield, but my understanding (see below) is that it requires nesting to do this.
using Setfield
struct Foo
a
b
c
end
x = Foo(1, 2, 3)
y = @set (@set x.a = 'a').b = 'b' # making this simpler?
This is a simplified version of my set function which takes a single argument. It can be extended for a tuple:
function set(str,var,val)
!any(i->i==var, fieldnames(typeof(str))) && @warn "\n No field in struct $(typeof(str)) is named $(var)!\n Fields are $(fieldnames(typeof(str)))"
dict = Dict{Symbol,Any}()
for name in fieldnames(typeof(str))
if name == var
dict[name] = val
else
dict[name] = getfield(str,name)
end
end
x = NamedTuple{Tuple(keys(dict))}(values(dict))
str = typeof(str)(x...)
end
E.g.:
struct Foo
a
b
c
end
x = Foo(1, 2, 3)
y = set(x, :a, 5)
julia> y
Foo(5, 2, 3)
There must be more efficient ways to deal with this with macros as in Setfield.jl but I don’t use it in performance-critical parts of the code so it works for me.