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