# Struct with field types defined by parametric type

**URL:** <https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117>\
**Category:** Performance\
**Created:** [February 12, 2024, 8:17pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117 "2024-02-12T20:17:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattsignorelli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattsignorelli/32/221502_2.png) [@mattsignorelli](https://discourse.julialang.org/u/mattsignorelli)\
**Post date:** [February 12, 2024, 8:17pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/1 "2024-02-12T20:17:21Z")

</div>

Say I have a struct `MyStruct` such that

```julia
struct A
...
end

struct B
...
end

struct MyStruct{T <: Union{A, B}}
  t::T
  v::Vector
end

```

I want `v` to be of type `Vector{Float64}` if `T == A`, else if `T == B` then `v` should be of type `Vector{ComplexF64}`. How can I do that?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 12, 2024, 8:28pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/2 "2024-02-12T20:28:54Z")

</div>

yes. e.g.

```julia
struct MyStruct{S, T <: Union{A, B}}
  t::T
  v::Vector{S}
  MyStruct(t) = new(t, t isa A ? [1.0] : [1.0+0im])
end

```

---

<div class="post-metadata">

**Author:** ![mattsignorelli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattsignorelli/32/221502_2.png) [@mattsignorelli](https://discourse.julialang.org/u/mattsignorelli)\
**Post date:** [February 12, 2024, 9:31pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/3 "2024-02-12T21:31:33Z")

</div>

I know I could do this already. However based on [this section of the manual](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-containers) , I am concerned about performance with such a solution

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [February 12, 2024, 9:41pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/4 "2024-02-12T21:41:51Z")

</div>

Code warntype reports no type instabilities and performance overhead seems minimal:

```julia
using BenchmarkTools

module MyModule 

struct A; end
struct B; end

struct MyStruct{S, T <: Union{A, B}}
    t::T
    v::Vector{S}
end

MyStruct(t) = MyStruct(t, t isa A ? [1.0] : [1.0+0im])

struct MyComparisonStruct{T <: Union{A, B}}
    t::T
    v::Vector{Float64}
end

MyComparisonStruct(t) = MyComparisonStruct(t,[1.0])

end # module 

@btime MyModule.MyStruct(MyModule.A()) # 21.052 ns (1 allocation: 64 bytes)
@btime MyModule.MyComparisonStruct(MyModule.A()) # 21.104 ns (1 allocation: 64 bytes)

```

I had to move out the inner constructor though, it produced some weird error.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 12, 2024, 10:10pm UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/5 "2024-02-12T22:10:33Z")

</div>

In that case, we need to update that section of the manual because this type of pattern is the solution to that problem (so it’s bad if that is unclear).

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 13, 2024, 8:48am UTC](https://discourse.julialang.org/t/struct-with-field-types-defined-by-parametric-type/110117/6 "2024-02-13T08:48:53Z")

</div>

I’d rewritten that in a way that emphasizes the compile-time resolution

```julia
struct MyStruct{T <: Union{A, B}, S}
    t::T
    v::Vector{S}

    MyStruct{A, Float64}(t, v) = new{A, Float64}(t, v)
    MyStruct{B, ComplexF64}(t, v) = new{B, ComplexF64}(t, v)

    MyStruct(t::A, v) = new{A, Float64}(t, v)
    MyStruct(t::B, v) = new{B, ComplexF64}(t, v)
end

```
