Type Casting in Swift
Written by Team Kodeco
Type casting in Swift is the process of converting an object from one type to another.
The syntax of type casting in Swift is as follows:
expression as Type
Her’s an example of using Swift type casting:
let stringValue = "hello"
let intValue = 42
let doubleValue = Double(intValue) // 42.0
let stringDoubleValue = Double(stringValue) // This will fail and return nil
The first typecast converts an integer to a Double
.
The second typecast tries to convert a string “hello” to a Double
. Since “hello” is not a number, the typecast fails and returns nil
.
Downcasting vs. Upcasting
There are two types of type casting in Swift: downcasting and upcasting.
Downcasting is used to convert a value from a superclass type to a subclass type. The syntax for downcasting is as follows:
let instance = superclassValue as? SubclassType
The as?
operator is used to perform a downcast and returns an optional value of type SubclassType
. If the downcast is successful, the optional will contain the downcasted value, otherwise it’ll be nil
.
Upcasting is used to convert a value from a subclass type to a superclass type. The syntax for upcasting is as follows:
let instance: SuperclassType = subclassValue as SuperclassType
The as
operator is used to perform an upcast. If the upcast is successful, the expression will be of type SuperclassType
, otherwise it’ll cause a compile-time error.
In both cases, the type casting is performed at runtime, which means that the type of the value can only be determined at runtime, not at compile time. This is why type casting can be unsafe, so it’s important to use it with caution and check the type of the casted value before using it.
Downcasting in Swift
An example for downcasting:
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
let library = [
Song(name: "Never Gonna Give You Up", artist: "Rick Astley"),
Movie(name: "The Matrix", director: "Wachowski"),
Song(name: "Smooth Criminal", artist: "Michael Jackson"),
Movie(name: "Inception", director: "Christopher Nolan"),
Song(name: "Billie Jean", artist: "Michael Jackson"),
Movie(name: "The Dark Knight", director: "Christopher Nolan"),
]
for item in library {
if let movie = item as? Movie {
print("Movie: \(movie.name), Director: \(movie.director)")
} else if let song = item as? Song {
print("Song: \(song.name), Artist: \(song.artist)")
}
}
In this example, you have a base class MediaItem
with a single property name
and a Song
and Movie
class that both inherit from MediaItem
. Song
adds an additional artist
property, and Movie
adds a director
property.
Then you create an array of library with a mix of Song and Movie instances.
Finally, you use a for-loop to iterate over the library array and downcast each MediaItem
instance to either a Song
or a Movie
using the as?
operator. If the downcast is successful, print the details of the Song
or Movie
instance, otherwise, skip the item.
This code outputs:
Song: Never Gonna Give You Up, Artist: Rick Astley
Movie: The Matrix, Director: Wachowski
Song: Smooth Criminal, Artist: Michael Jackson
Movie: Inception, Director: Christopher Nolan
Song: Billie Jean, Artist: Michael Jackson
Movie: The Dark Knight, Director: Christopher Nolan
Upcasting in Swift
Using the same classes, here is an example on Upcasting:
let song = Song(name: "Shake it Off", artist: "Taylor Swift")
let movie = Movie(name: "Avatar", director: "James Cameron")
var library = [song, movie]
// Upcasting
for item in library {
if let mediaItem = item as? MediaItem {
print("Media item: \(mediaItem.name)")
}
}
In this example, song
and movie
instances are cast to MediaItem
, so that they can be stored in a library array which only holds MediaItem
objects. This is an example of upcasting, where a subclass type is converted to its superclass type.