# How to create a struct that contains an SVector of structs?

**URL:** <https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110>\
**Category:** General Usage\
**Tags:** question\
**Created:** [March 18, 2022, 9:37pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110 "2022-03-18T21:37:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 18, 2022, 9:37pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/1 "2022-03-18T21:37:44Z")

</div>

The following code does not work:

```julia
using StaticArrays, Parameters
import Base.zero

const SEGMENTS = 6

# struct, defining the physical parameters of one spring
@with_kw mutable struct Spring{I, S}
    p1::I = 1 # number of the first point
    p2::I = 2 # number of the second point
    length::S = 1.0 # Current unstressed spring length
    c_spring::S = 1.0 # 
    damping::S = 0.1 # 
end

const SP = Spring{Int16, Float64}

function zero(::Type{SP})
    s = SP()
    s.p1 = 0
    s.p2 = 0
    s.length = 0.0
    s.c_spring = 0.0
    s.damping = 0.0
    s
end

@with_kw mutable struct KPS4{S, P, SP} 
    masses::MVector{P, S} = ones(P)
    springs::SVector{P-1, SP} = SVector{P-1, SP}(zeros(SP, P-1))
end

function KPS4()
    KPS4{Float64, SEGMENTS+1, SP}()
end

kps = KPS4()

```

Error message:

```julia
julia> include("src/bug.jl")
ERROR: LoadError: MethodError: no method matching -(::TypeVar, ::Int64)
Closest candidates are:
  -(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at ~/packages/julias/julia-1.7/share/julia/base/int.jl:86
  -(::Base.TwicePrecision, ::Number) at ~/packages/julias/julia-1.7/share/julia/base/twiceprecision.jl:293
  -(::LinearAlgebra.UniformScaling, ::Number) at ~/packages/julias/julia-1.7/share/julia/stdlib/v1.7/LinearAlgebra/src/uniformscaling.jl:147
  ...
Stacktrace:
 [1] top-level scope
   @ ~/.julia/packages/Parameters/MK0O4/src/Parameters.jl:611
 [2] include(fname::String)
   @ Base.MainInclude ./client.jl:451
 [3] top-level scope
   @ REPL[1]:1
in expression starting at /home/ufechner/repos/KiteModels/src/bug.jl:27

```

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 18, 2022, 9:44pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/2 "2022-03-18T21:44:36Z")

</div>

The following code works fine:

```julia
using StaticArrays, Parameters
import Base.zero

const SEGMENTS = 6

# struct, defining the phyical parameters of one spring
@with_kw mutable struct Spring{I, S}
    p1::I = 1 # number of the first point
    p2::I = 2 # number of the second point
    length::S = 1.0 # Current unstressed spring length
    c_spring::S = 1.0 # 
    damping::S = 0.1 # 
end

const SP = Spring{Int16, Float64}

function zero(::Type{SP})
    s = SP()
    s.p1 = 0
    s.p2 = 0
    s.length = 0.0
    s.c_spring = 0.0
    s.damping = 0.0
    s
end

springs = SVector{3, SP}(zeros(SP, 3))

```

Output:

```julia

julia> include("src/working.jl")
3-element SVector{3, SP} with indices SOneTo(3):
 SP
  p1: Int16 0
  p2: Int16 0
  length: Float64 0.0
  c_spring: Float64 0.0
  damping: Float64 0.0

 SP
  p1: Int16 0
  p2: Int16 0
  length: Float64 0.0
  c_spring: Float64 0.0
  damping: Float64 0.0

 SP
  p1: Int16 0
  p2: Int16 0
  length: Float64 0.0
  c_spring: Float64 0.0
  damping: Float64 0.0

```

But why can’t I use this array of structs as element of another struct?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 18, 2022, 10:03pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/3 "2022-03-18T22:03:13Z")

</div>

> `ERROR: LoadError: MethodError: no method matching -(::TypeVar, ::Int64)`

This comes from

```julia
@with_kw mutable struct KPS4{S, P, SP} 
    masses::MVector{P, S} = ones(P)
    springs::SVector{P-1, SP} = SVector{P-1, SP}(zeros(SP, P-1))
end

```

Most specifically because of `springs::SVector{P-1, SP} = ...`. You cannot do arithmetic with the type parameters of a parameterized `struct` in the definition of its fields. Julia simply do not support it. If I am not wrong the [ComputedFieldTypes package](https://github.com/vtjnash/ComputedFieldTypes.jl) can be used to overcome this limitation (not sure if in all cases).

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 18, 2022, 10:20pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/4 "2022-03-18T22:20:53Z")

</div>

Ok, this works:

```julia
using StaticArrays, Parameters
import Base.zero

const SEGMENTS = 6

# struct, defining the phyical parameters of one spring
@with_kw mutable struct Spring{I, S}
    p1::I = 1 # number of the first point
    p2::I = 2 # number of the second point
    length::S = 1.0 # Current unstressed spring length
    c_spring::S = 1.0 # 
    damping::S = 0.1 # 
end

const SP = Spring{Int16, Float64}

function zero(::Type{SP})
    s = SP()
    s.p1 = 0
    s.p2 = 0
    s.length = 0.0
    s.c_spring = 0.0
    s.damping = 0.0
    s
end

@with_kw mutable struct KPS4{S, P, Q} 
    masses::MVector{P, S} = ones(P)
    springs::Vector{Q} = zeros(Q, P)
end

function KPS4()
    KPS4{Float64, SEGMENTS+1, SP}()
end

kps = KPS4()

```

But I want to have an SVector of Springs, not a vector. Any idea how to achieve that?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 18, 2022, 10:28pm UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/5 "2022-03-18T22:28:02Z")

</div>

This works:

```julia
using StaticArrays, Parameters
import Base.zero

const SEGMENTS = 6

# struct, defining the phyical parameters of one spring
@with_kw mutable struct Spring{I, S}
    p1::I = 1 # number of the first point
    p2::I = 2 # number of the second point
    length::S = 1.0 # Current unstressed spring length
    c_spring::S = 1.0 # 
    damping::S = 0.1 # 
end

const SP = Spring{Int16, Float64}

function zero(::Type{SP})
    s = SP()
    s.p1 = 0
    s.p2 = 0
    s.length = 0.0
    s.c_spring = 0.0
    s.damping = 0.0
    s
end

@with_kw mutable struct KPS4{S, P, Q, SP} 
    masses::MVector{P, S} = ones(P)
    springs::SVector{Q, SP} = zeros(SP, Q)
end

function KPS4()
    KPS4{Float64, SEGMENTS+1, SEGMENTS, SP}()
end

kps = KPS4()

```

Slightly inconvenient, but not much…

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 19, 2022, 12:00am UTC](https://discourse.julialang.org/t/how-to-create-a-struct-that-contains-an-svector-of-structs/78110/6 "2022-03-19T00:00:10Z")

</div>

My pleasure. You did most of the work. I just gave a nudge in the right direction.
