Struct with fixed array sizes

Thanks, that’s helpful!

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
    # d::Union{Int32, Int64}
    function Test(; N=er(), a=er(), b=er(), c=er())
       d = b+c
       new(N, a, b, c, d)

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}
    Test{N}(a, b, c) where {N} = new(a, b, c, b + c)
function Test(; a::Integer, b::AbstractVector{<:Integer}, c::AbstractVector{<:Integer})
    length(b) == length(c) || throw(DimensionMismatch())
    return Test{length(b)}(a, b, c)

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.


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