Struct copy with change in the value of fields

Hi,

I have an anoying situation where I want to copy a variable of composed type by changing a value of the field which may in turn change the type. Here is an example


# in my application, the following struct contains ~20 fields...
struct A{T,vectype}
    p::T
    v::vectype
end

a = A(Int32(1), rand(10))

is of type A{Int32,Array{Float64,1}}. What I would like to do is something like this

b = copy(a, p = 0.21)

I face two issues. The first is I want to change an element, so writing this is anoying

b = A(p = 0.21, v = a.v) # I would have to write every field :frowning:

I cant do

b = deepcopy(a)
b.p = 0.21

as the types dont match.

Does anybody have a solution please?

Thank you,

2 Likes

Use Setfield.jl:

julia> using Setfield

julia> b = @set a.p = 0.21;

julia> typeof(b)
A{Float64,Array{Float64,1}}
5 Likes

Thank you!

JuliaObjects/Accessors.jl: Update immutable data (github.com) as per 2023

You can define a constructor function to create a new struct instance using an old one’s default values. If you have a struct S:

struct S
    a
    b
    S(a, b) = new(a, b)
end

You can define:

S(x::S; a=x.a, b=x.b) = S(a, b)

Then:

old = S("a", "b")    # S("a", "b")
new = S(old; b=2)    # S("a", 2)

yeah but imagine that there are 50 fields

It’s a pain if you have 50 fields. But if you just have one struct for which you need this, and don’t wish to download a package just for this one struct, this is an option.

This is an old post and looks like you found a solution. I just wanted to write my response in case someone with a similar problem lands on this thread. They can make a more informed choice knowing there are simpler options for simpler cases.