Adding new field to existing structure

I am trying to learn more about the way to organize my Julia code. I know from the documentation that I can create a structure to hold some data like this:

## The structure below has lots of fields, I am just showing one as example
struct Person
p = Person(2)
println("Number of arms = ", p.nArms)

I would like to learn how to add a new field to the existing structure created above:

 nLegs = 2

Such that I can now have a new variable:

pritln("Number of legs = ", p.nLegs)

If I create data during my code execution, is there any way that I can add it to an existing structure that does not have a field created for it? Or should I carry the new data using variables throughout the code (without a structure definition)?

No, you canĀ“t add new fields to a struct. If you need that kind of flexibility, probably you want a Dict.

julia> d = Dict{String,Int}("number_of_arms"=>5, "number_of_legs"=>6)
Dict{String, Int64} with 2 entries:
  "number_of_arms" => 5
  "number_of_legs" => 6

julia> d["number_of_arms"]

julia> d["number_of_heads"] = 4

julia> d
Dict{String, Int64} with 3 entries:
  "number_of_arms"  => 5
  "number_of_heads" => 4
  "number_of_legs"  => 6

(there are some alternatives, like using named tuples, but be careful anyway, this kind of flexibility can cause important performance problems:

julia> t = (nArms=1, nLegs=4)
(nArms = 1, nLegs = 4)

julia> t = (t..., nHeads = 5)
(nArms = 1, nLegs = 4, nHeads = 5)

julia> t.nHeads

If you need to add fields dynamically to your data, then you probably need a Dict instead of a struct.


> const Person = Dict{Symbol, Any}

> p1 = Person(:nArms => 2)
Dict{Symbol, Any} with 1 entry:
  :nArms => 2

> p1[:nLegs] = 2; p1
Dict{Symbol, Any} with 2 entries:
  :nLegs => 2
  :nArms => 2

If you want to have some mandatory as well as some optional fields, then you need to create an explicit constructor, or a struct with explicitly accessor methods (see Base.getproperty, Base.setproperty!) for details. E.g.,

> person(; nArms = 2) = Person(:nArms => nArms)

> p2 = person(nArms = 3)
Dict{Symbol, Any} with 1 entry:
  :nArms => 3