Type casting is a way to check the type of an instance and/or to treat the instance as a specified type. In Swift we use the is
keyword to check if an instance is of a specific type and the as
keyword to treat an instance as a specific type.
The following example shows how we would use the is
keyword:
if person is SwiftProgrammer { print("\(person.firstName) is a Swift Programmer") }
In this example, the conditional statement returns true
if the person
instance is of the SwiftProgrammer
type or false
if it isn't. We can also use the switch
statement (as shown in the next example) if we want to check for multiple types.
for person in people { switch (person) { case is SwiftProgrammer: print("\(person.firstName) is a Swift Programmer") case is FootballPlayer: print("\(person.firstName) is a Football Player") default: print("\(person.firstName) is an unknown type") } }
We can use the where
statement in combination with the is
keyword to filter an array to only return instances of a specific type. In the next example, we filter an array that contains instances of the PersonProtocol
to only return those elements of the array that are instances of the SwiftProgrammer
type:
for person in people where person is SwiftProgrammer { print("\(person.firstName) is a Swift Programmer") }
Now let's look at how we would cast an instance to a specific type. To do this, we can use the as
keyword. Since the cast can fail if the instance is not of the specified type, the as
keyword comes in two forms: as?
and as!
. With the as?
form, if the casting fails it returns a nil
; with the as!
form, if the casting fails we get a runtime error. Therefore, it is recommended to use the as?
form unless we are absolutely sure of the instance type or we perform a check of the instance type prior to doing the cast.
The following example shows how we would use the as?
keyword to attempt to cast an instance of a variable to the SwiftProgammer
type:
if let p = person as? SwiftProgrammer { print("\(person.firstName) is a Swift Programmer") }
Since the as?
keyword returns an optional, in the last example we could use optional binding to perform the cast. If we are sure of the instance type, we can use the as!
keyword as shown in the next example
for person in people where person is SwiftProgrammer { let p = person as! SwiftProgrammer }
Now let's see how we can use associated types with protocols.