As we've seen previously, an object can adopt one or more protocols, allowing us to create different objects with the same type:
protocol MediaItem {
var name: String { get }
}
struct Movie: MediaItem {
let name: String
let director: String
}
struct Song: MediaItem {
let name: String
}
var beetlejuice: MediaItem = Movie(name: "Bettlejuice", director: "Tim Burton")
var underPressure: MediaItem = Song(name: "Under Pressure")
Checking type
Use is
operator to check the type of an instance. This returns a boolean result.
print(theMatrix is Movie) // True
print(theMatrix is Song) // False
print(underPressure is Movie) // False
print(underPressure is Song) // True
Type casting
In this example we could assign a Movie
type to a MediaItem
because Xcode is sure that a Movie
will always be a MediaType
. However, if we want to convert a MediaItem
to a Movie
(or to a Song
), we need to use as?
operator since it can fail, due to a MediaItem
instance won't be always a Movie
.
var beetlejuiceMovie = beetlejuice as? Movie
print(beetlejuiceMovie?.director)
Let's see another example where we have an array of MediaItem
. Then we will create two different arrays, one for Movie
and another one for Song
.
var mediaItems: [MediaItem] = [
Movie(name: "Bettlejuice", director: "Tim Burton"),
Movie(name: "Batman Forever", director: "Tim Burton"),
Song(name: "Under Pressure"),
Song(name: "Bohemian Rhapsody"),
Song(name: "We Will Rock You")
]
let movies: [Movie] = mediaItems.compactMap { $0 as? Movie }
let songs: [Song] = mediaItems.compactMap { $0 as? Song }
Be the first to comment