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:
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.
In case you want something pretty general but don’t want to bring in a package, here’s a simple function that does this for you, assuming you can use keyword arguments for your constructor:
julia> @kwdef struct AType; a::Float64; b::Int64; end;
julia> x = AType(1., 2);
julia> function copy_with_exceptions(x::T; kwargs...) where {T}
return T(; (f => getfield(x, f) for f in fieldnames(T))..., kwargs...)
end;
julia> copy_with_exceptions(x; b = 3)
AType(1.0, 3)
I’m not sure about performance here, but the pattern is simple enough if you don’t want to bring in Accessors.jl.