Here (Julia 1.5.3) I cannot define the struct as you did:
julia> mutable struct Particle{M,T} where {M <: Integer, T <: AbstractFloat}
x::MVector{M,T} # Current Position
v::MVector{M,T} # Current Velocity
end
ERROR: syntax: invalid type signature around REPL[24]:1
Stacktrace:
[1] top-level scope at REPL[24]:1
(that is not a good error message, clearly)
Anyway, as mentioned above, removing most of the restrictions works:
julia> mutable struct Particle{M,T}
x::MVector{M,T} # Current Position
v::MVector{M,T} # Current Velocity
end
julia> Particle(x::MVector{M,T}) where {M,T} = Particle(x,x)
Particle
julia> x = rand(MVector{3,Float64})
3-element MArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
0.2803399080247968
0.11607884285749992
0.6952047979171718
julia> Particle(x)
Particle{3,Float64}([0.2803399080247968, 0.11607884285749992, 0.6952047979171718], [0.2803399080247968, 0.11607884285749992, 0.6952047979171718])
And note that the final Particle is completely type-specific, as you want.
One additional thing: you may not need (want) mutable static arrays. You can work with immutable static arrays, and mutate the fields of your mutable structs.
julia> using StaticArrays
julia> mutable struct Particle{M,T}
x::SVector{M,T} # Current Position
v::SVector{M,T} # Current Velocity
end
julia> p = Particle(rand(SVector{3,Float64}),rand(SVector{3,Float64}))
Particle{3,Float64}([0.9743653173834737, 0.3775182744632197, 0.37405647923023433], [0.5096490765009536, 0.530903496717793, 0.1187232054938756])
julia> y = SVector{3,Float64}(0., 0., 0.)
3-element SArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
0.0
0.0
0.0
julia> p.x = y
3-element SArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
0.0
0.0
0.0
julia> p
Particle{3,Float64}([0.0, 0.0, 0.0], [0.5096490765009536, 0.530903496717793, 0.1187232054938756])
(this mutation is allocation-free, and fast)