DEV Community

Naveen Ragul B
Naveen Ragul B

Posted on • Edited on

Swift - Type Casting

Type casting is a way to treat instance of a type as a different superclass or subclass and to check the type of an instance, implemented with the as and is operators.

It can be also used to check whether a type conforms to a protocol.

Checking Type

  • is operator is used to check whether an instance is of a certain type or it's subclass type.

example :

class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}
Enter fullscreen mode Exit fullscreen mode
class Movie: MediaItem {
    var director: String
    init(name: String, director: String) {
        self.director = director
        super.init(name: name)
    }
}

class Song: MediaItem {
    var artist: String
    init(name: String, artist: String) {
        self.artist = artist
        super.init(name: name)
    }
}
Enter fullscreen mode Exit fullscreen mode
let library = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]

var movieCount = 0
var songCount = 0

for item in library {
    if item is Movie {
        movieCount += 1
    } else if item is Song {
        songCount += 1
    }
}
Enter fullscreen mode Exit fullscreen mode

Downcasting

A constant or variable of a certain class type may actually refer to an instance of a subclass using type cast operator (as? or as!).

  1. as?, returns an optional value
  2. as!, attempts the downcast and force-unwraps the result

Use as! when you are sure that downcast will succeed and as? when you are not sure.

example :

for item in library {
    if let movie = item as? Movie {
        print("Movie: \(movie.name), dir. \(movie.director)")
    } else if let song = item as? Song {
        print("Song: \(song.name), by \(song.artist)")
    }
}
Enter fullscreen mode Exit fullscreen mode

Type Casting for Any and AnyObject

Swift provides two special types for working with nonspecific types:

  1. Any can represent an instance of any type at all, including function types.
  2. AnyObject can represent an instance of any class type.
var things: [Any] = []

things.append(0)
things.append(0.0)
things.append(3.14159)
things.append("hello")
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
Enter fullscreen mode Exit fullscreen mode
  • The Any type represents values of any type, including optional types. Swift gives you a warning if you use an optional value where a value of type Any is expected. If you really do need to use an optional value as an Any value, you can use the as operator to explicitly cast the optional to Any.

example :

let optionalNumber: Int? = 3
things.append(optionalNumber)        // Warning
things.append(optionalNumber as Any) // No warning
Enter fullscreen mode Exit fullscreen mode

To discover the specific type of a constant or variable thatโ€™s known only to be of type Any or AnyObject, you can use an is or as pattern in a switch statementโ€™s cases.

example :

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        print("a movie called \(movie.name), dir. \(movie.director)")
    case let stringConverter as (String) -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)