I’m trying to use metraprogramming to create structures on the fly. I managed to make a construtor for a vanilla struct as:
function makestruct(name::Symbol, ndim::Integer)
dims = (:x, :y, :z)
fields = [:( $(dims[i]) ) for i in 1:ndim]
@eval begin
struct $(name)
$(fields...)
end
end
end
However, I can’t manage to make a parametric struct with metaprogramming. In the end what I would like to simply generate:
It seems like your existing code is already almost there–you just need to add T in the appropriate places:
julia> function makestruct(name::Symbol, ndim::Integer)
dims = (:x, :y, :z)
fields = [:( $(dims[i])::T ) for i in 1:ndim]
@eval begin
struct $(name){T}
$(fields...)
end
end
end
makestruct (generic function with 1 method)
julia> makestruct(:bar, 2)
julia> bar(1, 2)
bar{Int64}(1, 2)
By the way, you might be interested in StaticArrays.FieldVector, which is designed to let types like this operate as statically sized vectors in a convenient way: API · StaticArrays.jl
Oh, and also, if your actual use-case really is small vectors with x, y, z labels, note that you can already use StaticArrays.SVector for that with no changes at all:
julia> using StaticArrays
julia> v = SVector{2, Float64}(1.0, 2.0)
2-element SVector{2, Float64} with indices SOneTo(2):
1.0
2.0
julia> v.x
1.0
julia> v.y
2.0