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
    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!