Consider the following struct using Parameters.jl
:
@with_kw struct MyStruct
color1::String = "white"
color2::String = "black"
style1::String = "cool"
style2::String = "hot"
end
Now, what I'd like to do is to enable the user to create a new instance of this struct with something like:
s = MyStruct(color="blue")
This should be equivalent to s = MyStruct(color1="blue", color2="blue")
. Similarly for style, thus,
s = MyStruct(color="red", style="none")
.
Is there any "elegant" solution for such a problem?
You can use multiple dispatch using NamedTuple
s:
image.png
not that I'm competent to answer, but how about adding a field color
and an inner constructor that would check that color1 == color2
to set its value?
Patrick Toche said:
not that I'm competent to answer, but how about adding a field
color
and an inner constructor that would check thatcolor1 == color2
to set its value?
Can you give an example? The thing is, the color
field should be optional. It would be just a faster way of attributing color1
and color2
.
Elias Carvalho said:
You can use multiple dispatch using
NamedTuple
s:
image.png
Thanks, this seems to work. Although, it does not seems to work perfectly, because I have more fields other than color1
and color2
. And also, I'm using Parameters.jl
. The MyStruct(;kwargs...)
seems to break the constructor from Parameters.jl
Ok, I think I came up with a nice solution:
@with_kw struct _Struct
color::Union{String,Nothing} = nothing
color1::String = color === nothing ? "white" : color
color2::String = color === nothing ? "black" : color
style::Union{String,Nothing} = nothing
style1::String = style === nothing ? "blue" : style
style2::String = style === nothing ? "white" : style
end
This is overcomplicated, you can just put it in a regular constructor.
For example
struct MyStruct
color1::String
color2::String
style1::String
style2::String
end
MyStruct(; color = nothing,
color1 = color === nothing ? "white" : color,
color2 = color === nothing ? "black" : color,
style = nothing,
style1 = style === nothing ? "cool" : style,
style2 = style === nothing ? "hot" : style) =
MyStruct(color1, color2, style1, style2)
julia> MyStruct(color = "green", style1 = "warm")
MyStruct("green", "green", "warm", "hot")
@Andrey Oskin , your solution didn't work for me :/
The issue is that I'm using Parameters.jl
. So things get more complicated.
But Parameters.jl is doing exactly that, it generates keyword constructor. Just instead of relying on macro you can generate it explicitly. There is no need to restrict yourself to Parameters default.
Davi Sales Barreira has marked this topic as resolved.
Last updated: Dec 28 2024 at 04:38 UTC