Setfield fails for structs with "label"-like type annotations

Is this expected to fail?

julia> using Setfield

julia> struct C{S,T}
         i::T
       end

julia> c = C{Float64,Int}(1)
C{Float64, Int64}(1)

julia> @set! c.i = 2
ERROR: MethodError: no method matching C(::Int64)

In my practical case, the S field would be only for managing dispatch, but the result is the same.

1 Like

This behaviour is expected, but there are multiple ways to get what you want. One way is

struct C{S,T}
     s::S
     i::T
end

I like this design if S is an empty “trait type” e.g. sizeof(S) = 0. It has the advantage, that you can do things like @set c.s = S2().
If that is not an option, overload ConstructionBase.constructorof or ConstructionBase.setproperties for more complicated cases.

https://github.com/JuliaObjects/ConstructionBase.jl

4 Likes

I didn’t think of that, but actually that might be useful. Thanks.