Using type parameters

When defining functions, we have an option to annotate each argument with type information. The type of an argument can be a regular abstract type, concrete type, or a parametric type. Let's consider this sample function for exploding an array of game pieces:

# explode an array of objects
function explode(things::AbstractVector{Any})
for t in things
println("Exploding ", t)
end
end

The things argument is annotated with AbstractVector{Any}, which means that it can be any AbstractVector type that contains any object that is a subtype of Any (which is really just everything). To make the method parametric, we can just rewrite it with a T type parameter as follows:

# explode an array of objects (parametric version)
function explode(things::AbstractVector{T}) where {T}
for t in things
println("Exploding ", t)
end
end

Here, the explode function can accept any AbstractVector with the parameter T, which can be any subtype of Any. So, if we just pass a vector of Asteroid objects—that is, Vector{Asteroid}—it should just work. It also works if we pass a vector of symbols—that is, Vector{Symbol}. Let's give it a try:

Note that Vector{Asteroid} is actually a subtype of AbstractVector{Asteroid}. In general, we can say that SomeType{T} is a subtype of SomeOtherType{T} whenever SomeType is a subtype of SomeOtherType. But, if we are unsure, it is easy to check:

Perhaps we don't really want the explode function to take a vector of anything. Since this function is written for our space war game, we could restrict the function to accept a vector of any type that is a subtype of Thing. It can be easily achieved as follows:

# Same function with a more narrow type
function explode(things::AbstractVector{T}) where {T <: Thing}
for t in things
println("Exploding thing => ", t)
end
end

The where notation is used to further qualify the parameter with superclass information. Whenever a type parameter is used in the function signature, we must accompany it with a where clause for the same parameter(s).

Type parameters in function arguments allow us to specify a class of data types that fit within the constraint indicated inside the where clause. The preceding explode function can take a vector containing any subtype of Thing. This means that the function is generic in the sense that it can be dispatched with an unlimited number of types, as long as it satisfies the constraint.

Next, we will explore the use of abstract types as an alternative way to specify function arguments. At first glance, it looks fairly similar to using parametric types; however, there is a slight difference, which we will explain in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.36.192