julia> abstract type AbstractType end
julia> mutable struct MyAType <: AbstractType
a::Int64
end
When having an Array field of type MyAType in a struct, it can be initialized to an empty array within an inner constructor.
mutable struct MyArrType
intArr::Array{MyAType,1}
MyArrType() = new(MyAType[ ])
end
It works:
julia> a = MyAType(1)
MyAType(1)
julia> push!(A.intArr,a)
1-element Vector{MyAType}:
MyAType(1)
In contrary, when having a parametric struct:
mutable struct MyArrType2{T <: AbstractA}
intArr::Array{T,1}
MyArrType2() = new(T[])
end
ERROR: syntax: too few type parameters specified in "new{...}" around REPL[4]:1
Stacktrace:
[1] top-level scope
@ REPL[4]:1
The above struct can is functioning by defining an outer constructor:
MyArrType2{T}() where T <: AbstractType = MyArrayType2(T[])
When you write MyArrType() = new(T[]), what is the compiler supposed to initialise? An empty array of type T? But you haven’t told it what T is so it doesn’t know what to do.
The outer one works because you have told it what T is explicitly. Perhaps your inner constructor should be MyArrType{T}() = new(T[]) (but note I haven’t tested this).
I did not either tell the compiler what T is when declaring intArr::Array{T,1}.
Is not that one of the purposes of parametric types? to be able to write generic code that works for many arbitrary subtypes. I am still assuming that there is a good reason not to allow this with the operator new and there could be a hack to do it in a better way.
intArr::Array{T, 1} is fine because if you define your struct to be parametric, then as long as you tell the constructor what type you want it to construct then it will be able to do so. The problem with MyArrType2() is that you’re not telling the parametric type what T is.
MyArrType2{T}()? Compiler says “Ok, here is a intArr::Array{T,1}” MyArrType2()? Compiler says “what is T?”
Yes, see Constructors · The Julia Language for more information. But basically, inner constructors are just normal function definitions. You need to write them as you would do if you were outside the struct definition.
The only difference in terms of syntax between inner and outer constructors is that inner constructors have access to the special new() function. Otherwise, they use the exact same syntax.
Now you came out with the code with the least redundancies. Now I understand that where T
is less redundant than where T <: AbstractType
and the operator new does not need to be qualified with the type T