Sometimes, we need to support multiple types in a field. This can be done using a Union type, which is defined as a type that can accept any specified types. To define a Union type, we can just enclose the types within curly braces after the Union keyword. For example, the Union type of Int64 and BigInt can be defined as follows:
Union{Int64,BigInt}
These Union types are quite useful when you need to incorporate data types that come from different data type hierarchies. Let's extend our personal asset example further. For instance, say that we need to incorporate some exotic items into our data model, which may include things such as art pieces, antiques, paintings, and so on. These new concepts may have already been modeled with a different type hierarchy, as follows:
abstract type Art end
struct Painting <: Art
artist::String
title::String
end
As it turns out, my wife likes to collect paintings, and so I can just generalize the BasketOfStock type as BasketOfThings, as follows:
struct BasketOfThings
things::Vector{Union{Painting,Stock}}
reason::String
end
The things inside the vector can be Stock or Painting. Remember that Julia is a strongly typed language, and it is important that the compiler knows what kinds of data type can fit into an existing field. Let's see how it works:
To create a vector that contains either Painting or Stock, we just specify the element type of the array in front of the square brackets, as in Union{Painting,Stock}[stock, monalisa].
The syntax for Union types can be very verbose, especially when there are more than two types, so it is quite common for a constant to be defined with a meaningful name that represents the Union type:
const Thing = Union{Painting,Stock}
struct BasketOfThings
thing::Vector{Thing}
reason::String
end
As you can see, Thing is much easier to read than Union{Painting,Stock}. Another benefit is that the Union type may be referenced in many parts of the source code. When we need to add more types later—for instance, an Antique type—then we only need to change it in one place, which is the definition of Thing. This means that the code can be maintained more easily.
In this section, although we have chosen to use concrete types such as Stock and Painting for our example, there is no reason why we cannot use abstract types such as Asset and Art for the Union type.
Next, we will continue to learn how to work with type operators.