Vector{Integer} vs Vector{Int64} in mutable struct template

Hi,

I can’t understand why I can’t pass Int64 instead of Integer.
I need to create an instance of the following struct:

mutable struct MyStruct{T}
  a::Array{Integer,1}
  b::Array{Integer,1}
  c::Array{T,1}
end

a = ones(Integer, 2)
b = ones(Int64, 3)
c = ones(Float32, 3)

MyStruct(a, b, c)

Why I do get error:

no method matching MyStruct(::Vector{Integer}, ::Vector{Int64}, ::Vector{Float32})
Closest candidates are:
  MyStruct(::Vector{Integer}, ::Vector{Integer}, ::Vector{T}) where T at REPL[1]:2

As I know Int64 is a subclass of Integer

How to pass Int64 instead of Integer?

Use Vector{Int64} or simply Vector{Int} which is the same.

Your error message would be solved using Vector{<:Integer} , because of this, but probably you don’t want that, because it is an abstract type.

3 Likes

Thank you very much!

The approach Vector{<:Integer} seems to be working though I still don’t understand the reason of that error.

Vector{Int64} is a vector that cannot contain, for instance, a Int32. Thus, Vector{Int64} is not a subtype of Vector{Integer}, because the former has a constraint that the later does not have.

The linked thread discusses exactly that, and these are my notes on the subject (my understanding of these things is more empirical, thus my explanation may be easier to understand than that of the computer scientists).

3 Likes

Be aware that this has negative performance implications. You can do

mutable struct MyStruct{S<:Integer, T}
    a::Array{S,1}
    b::Array{S,1}
    c::Array{T,1}
end

instead.

Also, are you sure your struct must be mutable? Arrays are already mutable in their own right, so you can modify them even if MyStruct itself is immutable.

1 Like

Thank you for the information

Yes the struct must be mutable asthere are also non-array elements that should be possible to modify