# How does a dictionary store structs?

**URL:** <https://discourse.julialang.org/t/how-does-a-dictionary-store-structs/57866>\
**Category:** General Usage\
**Created:** [March 24, 2021, 1:42pm UTC](https://discourse.julialang.org/t/how-does-a-dictionary-store-structs/57866 "2021-03-24T13:42:05Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [March 24, 2021, 1:42pm UTC](https://discourse.julialang.org/t/how-does-a-dictionary-store-structs/57866/1 "2021-03-24T13:42:05Z")

</div>

Consider for a moment the following `struct`s:

```julia
abstract type AbstractTransport end

struct Warp
    limit::Float32
end

struct Galaxy <:AbstractTransport
    name::String
    drive::Warp
end

struct Intrepid <:AbstractTransport
    name::String
    drive::Warp
    doctor::String # This is specific to Intrepid
end

```

```julia
uss_enterprise = Galaxy("USS Enterprise-D",Warp(9.0))
uss_voyager = Intrepid("USS Voyager",Warp(9.9),"Emergency Medical Hologram")

ships = Dict{String,AbstractTransport}((uss_enterprise.name => uss_enterprise),
                                        (uss_voyager.name => uss_voyager))

println(ships["USS Voyager"].doctor)

```

When both starships get stored in `ships` it’s stored as an `AbstractTransport`, why can I retrieve `USS Voyager` and access the `doctor` attribute?

I’m used to the OO model where anything declared in the subclass is specific to that subclass, and can’t be accessed by it’s parent. As you can see, this isn’t the case here, all the attributes are specific to each `struct`.

I guess the larger more accurate question would be, how are the `struct`s stored in `ships`, so that I can access the specific attributes of each `struct`? (I’m looking at this from an OO perspective, which probably isn’t a good idea).

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 24, 2021, 1:53pm UTC](https://discourse.julialang.org/t/how-does-a-dictionary-store-structs/57866/2 "2021-03-24T13:53:29Z")

</div>

> [@anon60034542](#):
>
> When both starships get stored in `ships` it’s stored as an `AbstractTransport` , why can I retrieve `USS Voyager` and access the `doctor` attribute?
> 
> I’m used to the OO model where anything declared in the subclass is specific to that subclass, and can’t be accessed by it’s parent.

Right–you’re thinking of how things work in a language like C++, where there’s a difference between the compile-time type (e.g. `AbstractTransport`) and the run-time type (e.g. `Intrepid`). Julia doesn’t have this distinction at all (see this comment: [Compile-time vs run-time actions - #3 by StefanKarpinski](https://discourse.julialang.org/t/compile-time-vs-run-time-actions/17035/3)). No matter how you store an `Intrepid` or what generic container you use to hold it, Julia will always remember that it was an `Intrepid` and will always let you treat it as such.

As an extreme example, consider a `Vector{Any}` like `[]`. In a language with different compile-time and run-time types, you wouldn’t be able to do _anything_ with the contents of such an array, since the `Any` abstract type doesn’t provide any methods. This clearly isn’t the case in Julia, where you can store anything you want in a `Vector{Any}` and still access each individual element in its proper type.

As for how this is actually stored, it’s probably best to focus on what the language actually ensures, which is: No matter what the value type of your `Dict` is, an `Intrepid` will always be an `Intrepid`. In practice, if you have a dictionary with a non-concrete value type, then there will be some kind of metadata stored giving the actual type of each value. If you have a `Dict{String, Intrepid}`, then there’s no need for that metadata for each individual value, which is one reason why concrete container types are more efficient. I’m sure other more knowledgeable people can give you details on the exact form of that metadata (my mental model is “a pointer and a type tag”), but that’s probably only necessary to understand if you actually want to modify the internals of Julia itself.
