# How to construct structs with implicitly typed fields?

**URL:** <https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398>\
**Category:** New to Julia\
**Created:** [March 3, 2021, 11:11am UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398 "2021-03-03T11:11:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![triceert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/triceert/32/21896_2.png) [@triceert](https://discourse.julialang.org/u/triceert)\
**Post date:** [March 3, 2021, 11:11am UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/1 "2021-03-03T11:11:06Z")

</div>

From the documentation it is not clear to me how to achieve something like the following:

```julia
mutable struct foo {T<:Int64, S<:Array{Float64}}
   size::T
   matrix::S

   function foo(size::T) where {T}
       matrix = zeros(size,size)
       new(size,matrix) 
   end
end

```

I tried a few things and I always run into “too few type parameters defined” or when I try `new{T,S} new(size,matrix)` “S not defined”.

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)\
**Post date:** [March 3, 2021, 11:30am UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/2 "2021-03-03T11:30:20Z")

</div>

There are actually several things that can be improved here in order to work.

1. `Int64` is a concrete type, so you shouldn’t try to create something that is its “child”. It is better to constrain it to `Integer`.

2. What are you trying to accomplish exactly by subtyping the matrix as subtype from `Array{Float64}`? Do you mean that it should be able to accept only floating point numbers, or real numbers (including integers, rationals, etc)?

In any case, three things can be improved there:

2.A. Arrays are not covariant i.e.: `Array{Int64,1}` is not a subtype of `Array{Integer,1}`. The way to do that is `matrix::Array{<:Integer,1}`. The same is applied for `Float`.

2.B. It is better to subtype from `AbstractArray`, which also allows other things that act as `Array` although they are not exactly that.

2.C. The `Array` type needs two parameters: the element type (`Float64`, etc) and the dimensions (an integer). What you are looking for I think is `AbstractMatrix{<:Float}` or `AbstractMatrix{<:Number}`.

More things that yoyu may need to think about:

1. Is it really necessary that the type is `mutable`? If you want to change the size, it may be better to create a new object altogether.

2. Do you really need to create a type for this? Is not enough to have available `Matrix{Float64}` and its method `size`? If you want to ensure that it remains the same size, maybe you should take a look at `StaticArrays.jl`

---

<div class="post-metadata">

**Author:** ![triceert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/triceert/32/21896_2.png) [@triceert](https://discourse.julialang.org/u/triceert)\
**Post date:** [March 3, 2021, 11:57am UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/3 "2021-03-03T11:57:27Z")

</div>

Ok maybe I should clarify a little bit more what I want to achieve here. I have a very big and expensive ODE System (so I think StaticArrays won’t be beneficial for the performance.) I read the performance tips and as far as I understand I should localise as much variables as possible.

Therefore I want to pass some preallocated Arrays/ Vectors to the ODE-system where they will mutated in order to avoid heap allocations. I however want to be able to solve the system on different discretisation sizes, hence I need to be able to construct differently sized preallocation Arrays/Vectors when calling the ODE-system. So I use a closure like this:

`ode_prob = ODEProblem(du, u,p,t) -> mysystem(du,u,p,t,AllocationStruct(size))`

this works well with:

```julia
mutable struct AllocationStruct
   matrix_foo
   matrix_bar
   vector_u
   function AllocationStruct(size)
        matrix_foo = zeros(size,size)
        matrix_bar = similar(matrix_foo)
        vector_u = zeros(size)
        new(matrix_foo,matrix_bar,vector_u)
   end
end

```

So I try to construct some arrays/vectors that will contain reals from the size of the number discretisation points ` size` which is obviously a integer.

In the performance tips I read that it would be better if I actually define the types of the fields of `AllocationStruct` and this is what I’m trying to achieve.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 3, 2021, 12:07pm UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/4 "2021-03-03T12:07:48Z")

</div>

There is no need to use inner constructor here. Outer constructors are more safe, because they do not override default constructors.

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [March 3, 2021, 12:15pm UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/5 "2021-03-03T12:15:30Z")

</div>

> [@triceert](#):
>
> it would be better if I actually define the types of the fields of `AllocationStruct`

Are you looking for something like:

```julia
mutable struct AllocationStruct{R,S}
    matrix_foo::R
    matrix_bar::R
    vector_u::S
end

AllocationStruct(size) = AllocationStruct(zeros(size,size), zeros(size,size), zeros(size))

julia> AllocationStruct(4)
AllocationStruct{Matrix{Float64}, Vector{Float64}}([0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0], [0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0], [0.0, 0.0, 0.0, 0.0])

```

---

<div class="post-metadata">

**Author:** ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)\
**Post date:** [March 3, 2021, 12:20pm UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/6 "2021-03-03T12:20:23Z")

</div>

I think you can dismiss creating a whole type for this. Also, I don’t think you are using the closure right. If you want a function for preallocation, maybe something like this:

```julia
(n) -> (zeros(n,n),zeros(n,n),zeros(n))

```

---

<div class="post-metadata">

**Author:** ![Gregstrq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregstrq/32/20620_2.png) [@Gregstrq](https://discourse.julialang.org/u/Gregstrq)\
**Post date:** [March 3, 2021, 2:44pm UTC](https://discourse.julialang.org/t/how-to-construct-structs-with-implicitly-typed-fields/56398/7 "2021-03-03T14:44:02Z")

</div>

> [@triceert](#):
>
> I tried a few things and I always run into “too few type parameters defined” or when I try `new{T,S} new(size,matrix)` “S not defined”.

Function `new` needs to know the concrete parameters of the struct that you are trying to create. When you try to use `new{T,S}`, the value of `T` is known from dispatch, but `S` is an undefined variable. The problem should be fixed if you use `new{T, typeof(matrix)}` instead.

Why do you need to store the size of the matrix as a separate field in the structure?  
You can always access the size of the matrix using `size(matrix)`. For an NxM matrix, it will return the tuple `(N, M)`. If you want to acces the size along dimension `dim`, you can use `size(matrix, dim)`. For example, `size(matrix, 1)` should return `N`.
