Structs
Structs are a great way to represent data in a compact and easy-to-understand way. Additionally, there is so much that can be accomplished with just an array of struct.
Defining a struct
In Julia, the struct
keyword defines a new Composite Type, based on given field names, and optionally annotated individual types.
By default, structs cannot be modified once initialized (i.e. are inmutable unless explicitly defined as a mutable struct
)
Let’s say we want to create a Location
type, containing a name, and (lat,lon)
coordinates. We can do this as follows:
struct Location
name::String
lat::Float32
lon::Float32
end
To initialize a struct with values, the default constructor is simply using the struct name as you would use a function:
loc1 = Location("Los Angeles", 34.0522,-118.2437)
We can access the struct fields with the dot notation, as is common in several languages:
loc1.name # "Los Angeles"
loc1.lat # 34.0522
loc1.lon # -118.2437
Having defined this Location struct, we can do things like for example defining a vector of Locations called sites
, and dynamically fill it with Location elements:
sites = Location[]
push!(sites, Location("Los Angeles", 34.0522,-118.2437))
push!(sites, Location("Las Vegas", 36.1699,-115.1398))
Notice that a very similar result could have been obtained via Named Tuples. Introducing a new Type such as our Location type can be convenient for additional clarity.
Mutable Structs
If we want to be able to modify the components of a struct after it has been initialized, we need to declare a mutable struct
, as follows:
mutable struct mLocation
name::String
lat::Float32
lon::Float32
end
We can then do things like:
loc1 = mLocation("Los Angeles", 34.0522,-118.2437)
loc1.name = "LA"
Base.@kwdef: Defaults Values and Keyword-Based Constructors
The Base.@kwdef
macro is a helpful tool that enables the use of default values in structs, and also keyword-based constructors.
For example, we can do the following:
Base.@kwdef mutable struct Param
Δt :: Float64 = 0.1
n :: Int64
m :: Int64
end
P = Param(m=50, n=35)
Note: since Julia 1.9, Base exports @kwdef
, so you don’t need to add the prefix, and can use @kwdef
instead of Base.@kwdef
.
Destructuring a Struct
Since Julia 1.7 we a syntax for structs that is very similar to what we had for NamedTuples:
(; n,Δt ) = P
This will get any field of P
that matches what we write on the left-hand side and turn it into a variable. Note that the order of the variables doesn’t matter, and that we don’t need to destructure all the fields.
While we can always access the fields of a struct by doing P.Δt
or P.n
, destructuring the struct enables us to create Δt
and n
variables automatically. This comes very handy if we have a rather long struct with many fields, and we rather use them as parameters instead.
print("The value of Δt is $(Δt)")
The value of Δt is 0.1