Use `struct` to define a composite type: a named group of fields that belong together. A game character, for example, can have a name, health, and a supply of arrows. The definition is a template; each character you create from it is an instance. section 7.1
Listing 7.1 Definition of a composite type
struct Archer
name::String #1
health::Int #2
arrows::Int #3
end
The `Archer` definition gives each field a name and a type. The `::` annotations specify that `name` holds a `String`, while `health` and `arrows` hold `Int` values. section 7.1
julia> robin = Archer("Robin Hood", 30, 24)
Archer("Robin Hood", 30, 24)
julia> william = Archer("William Tell", 28, 1)
Archer("William Tell", 28, 1)
julia> robin.name #1
"Robin Hood"
julia> robin.arrows #2
24
Create an instance by supplying its field values, then read a field with dot notation, as in `robin.arrows`. section 7.1
A dictionary can also group an archer’s information, but its differently typed values are stored as `Any` in this example. A struct instead specifies a type for each field. Its fields are fixed: an instance cannot acquire or lose fields at runtime, and field values must match their declared types. Those restrictions also help Julia generate optimized code. section 7.1 section 18.4
Composite types can contain other composite types. A rocket, for instance, can group payload, tank, and engine objects; larger designs can combine rocket stages and engine clusters. When individual fields must change after construction, define the type with `mutable struct`. section 8.0 section 7.5
A Julia struct may resemble a class in Python or Java, but it does not attach methods to the type or support implementation inheritance. A concrete struct can instead be declared a subtype of an abstract type, as with `mutable struct Archer <: Warrior`; the abstract type itself has no fields and cannot be instantiated. section 7.1 section 7.3.1













