I would like to be able to define a struct with some default values based on an input Dict.
The input is something like this:
d = Dict("A"=>1, "B"=>2, "C"=>"x", "D"=>[1,2])
And I would like to define a struct like below:
@kwdef struct MyStruct3
A::Int64 = 1
B::Int64 = 2
C::String = "x"
D::Vector{Int64} = [1,2]
end
I’ve got to a point where I can create a struct with type:
macro make_struct(name, dict)
symbols=[:($(Symbol(k))::$(typeof(v))) for (k, v) in eval(dict)]
:(@kwdef struct $(esc(name))
$(map(esc,symbols)...)
end)
end
@make_struct test d
But am not sure how to add default values to that, when I tried this:
macro make_struct(name, dict)
symbols=[:($(Symbol(k))::$(typeof(v))=$(v)) for (k, v) in eval(dict)]
:(@kwdef struct $(esc(name))
$(map(esc,symbols)...)
end)
end
Here, I would not use a macro as the code cannot be generated at compile time and you will have to call eval at runtime anyways. The following function works for me:
function def_dyn_struct(name::Symbol, spec::Dict)
fields = [:($(Symbol(k))::$(typeof(v)) = $(v)) for (k, v) in spec]
@eval @kwdef struct $(name)
$(fields...)
end
end
Your error seems to be related to the fact that A::Int64 = 1 is not valid inside a normal struct definition:
julia> struct Hu
A::Int64 = 1
end
ERROR: syntax: "A::Int64 = 1" inside type definition is reserved around REPL[39]:1
Further, when evaluating the code, I guess that esc is unnecessary (and also not handled gracefully by @kwdef):
julia> let name = :Ha
@eval @kwdef struct $(esc(name)) end
end
ERROR: syntax: invalid type signature around util.jl:589