# Struct with fixed array sizes

As a follow up (though let me know if I should move it to a separate question), I hope to create a `mutable struct` with fixed array sizes based on a dimension input parameter, `N`. The following MWE gives an error since `N` isn’t defined externally. Is the best/only way to do this by doing it internally before `new(...)`? Basically I want to allocate only `N` memory for an array whose dimension won’t change.

``````er() = throw(ArgumentError("Missing arguments: N, a, b, c"))
const D = Union{Array{Int64,1}, Array{Int32,1}}
mutable struct Test
N::Int64
a::Int64
b::Array{Int64,1}(N)
c::Array{Int64,1}(N)
d::D
# d::Union{Int32, Int64}
function Test(; N=er(), a=er(), b=er(), c=er())
d = b+c
new(N, a, b, c, d)
end
end

t=Test(; N=2, c=[3; 3], a=1, b=[2;2])

``````

The rhs of `::` in a struct should be a type. You need to do the allocation inside your constructor.

1 Like

`Array{Int64,1}(N)` is a value, not a type. If you want the length of the array to be a part of the type, use a static array (StaticArrays.jl package). Note also that there is no need to pass `N` as a parameter since it should be the length of `a` and `b`. I’m also unclear on why `d` is a union type when your constructor fixes it to be an array of `Int64`, and in general you should use concrete types for your fields if possible. For example

``````using StaticArrays
struct Test{N}
a::Int64
b::SVector{N,Int64}
c::SVector{N,Int64}
d::SVector{N,Int64}
Test{N}(a, b, c) where {N} = new(a, b, c, b + c)
end
function Test(; a::Integer, b::AbstractVector{<:Integer}, c::AbstractVector{<:Integer})
length(b) == length(c) || throw(DimensionMismatch())
return Test{length(b)}(a, b, c)
end
``````

Then you can do e.g. `Test(a=2, b=[3,4,5], c=[8,9,0])`.

Note that if you want the contents of the arrays to be mutable, you can keep it a `struct` but use an `MVector` for the elements. If you want to be able to change the field `a`, or you want to be able to change `b` to point to a different array (rather than changing the contents in-place), you need a `mutable struct`.

4 Likes

Great, `MVector` is exactly what I’m looking for. Thanks!