Easy Tutorial
❮ If Else Statement Swift Operators ❯

Swift Type Casting

Swift language type casting can determine the type of an instance. It can also be used to detect if an instance type belongs to its parent class or subclass.

In Swift, type casting is implemented using the is and as operators. is is used to check the type of a value, and as is used to convert types.

Type casting can also be used to check if a class implements a certain protocol.


Defining a Class Hierarchy

The following defines three classes: Subjects, Chemistry, and Maths, where Chemistry and Maths inherit from Subjects.

Here is the code:

class Subjects {
    var physics: String
    init(physics: String) {
        self.physics = physics
    }
}

class Chemistry: Subjects {
    var equations: String
    init(physics: String, equations: String) {
        self.equations = equations
        super.init(physics: physics)
    }
}

class Maths: Subjects {
    var formulae: String
    init(physics: String, formulae: String) {
        self.formulae = formulae
        super.init(physics: physics)
    }
}

let sa = [
    Chemistry(physics: "Solid Physics", equations: "Hertz"),
    Maths(physics: "Fluid Dynamics", formulae: "Gigahertz")
]

let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equations: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Gigahertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

The output of the above program is:

Instance physics is: Solid Physics
Instance equations: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Gigahertz

Checking Types

Type casting is used to detect if an instance type belongs to a specific instance type.

You can use it on class and subclass hierarchies to check the type of a specific class instance and convert the type of that class instance to other types within the hierarchy.

Type checking uses the is keyword.

The is operator checks if an instance belongs to a specific subclass. If the instance belongs to that subclass, the type check operator returns true, otherwise it returns false.

class Subjects {
    var physics: String
    init(physics: String) {
        self.physics = physics
    }
}

class Chemistry: Subjects {
    var equations: String
    init(physics: String, equations: String) {
        self.equations = equations
        super.init(physics: physics)
    }
}

class Maths: Subjects {
    var formulae: String
    init(physics: String, formulae: String) {
        self.formulae = formulae
        super.init(physics: physics)
    }
}

let sa = [
    Chemistry(physics: "Solid Physics", equations: "Hertz"),
    Maths(physics: "Fluid Dynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermal Physics", equations: "Decibels"),
    Maths(physics: "Astrophysics", formulae: "Megahurtz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
]
let samplechem = Chemistry(physics: "Solid State Physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equations: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Gigahertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0
for item in sa {
    // Returns true if it is an instance of Chemistry, otherwise returns false.
    if item is Chemistry {
        chemCount += 1
    } else if item is Maths {
        mathsCount += 1
    }
}

print("Chemistry subjects contain \(chemCount) topics, mathematics contains \(mathsCount) topics")

The above program execution output is:

Instance physics is: Solid State Physics
Instance equations: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Gigahertz
Chemistry subjects contain 2 topics, mathematics contains 3 topics

Downcasting

Downcasting, use type casting operators (as? or as!)

When you are not sure if the downcast will succeed, use the conditional form of type casting (as?). The conditional form of type casting always returns an optional value, and if the downcast is not possible, the optional value will be nil.

Only use the forced form (as!) when you are certain that the downcast will definitely succeed. Forcing a downcast to an incorrect type will trigger a runtime error.

class Subjects {
    var physics: String
    init(physics: String) {
        self.physics = physics
    }
}

class Chemistry: Subjects {
    var equations: String
    init(physics: String, equations: String) {
        self.equations = equations
        super.init(physics: physics)
    }
}

class Maths: Subjects {
    var formulae: String
    init(physics: String, formulae: String) {
        self.formulae = formulae
        super.init(physics: physics)
    }
}

let sa = [
    Chemistry(physics: "Solid State Physics", equations: "Hertz"),
    Maths(physics: "Fluid Dynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermal Physics", equations: "Decibel"),
    Maths(physics: "Astrophysics", formulae: "Megahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
]

let samplechem = Chemistry(physics: "Solid State Physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equations: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Gigahertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in sa {
    // Conditional form of type casting
    if let show = item as? Chemistry {
        print("Chemistry subject is: '\(show.physics)', \(show.equations)")
    // Forced form
    } else if let example = item as? Maths {
This program outputs the following results:

Instance physics is: Solid State Physics Instance equations: Hertz Instance physics is: Fluid Dynamics Instance formulas: Gigahertz Chemistry subject is: 'Solid State Physics', Hertz Math subject is: 'Fluid Dynamics', Gigahertz Chemistry subject is: 'Thermal Physics', Decibels Math subject is: 'Astrophysics', Megahertz Math subject is: 'Differential Equations', Cosine Series


---

## Type Casting for Any and AnyObject

Swift provides two special type aliases for dealing with uncertain types:

- `AnyObject` can represent an instance of any class type.
- `Any` can represent an instance of any type, including function types.

>

Note: It's always better to use explicit types in your code instead of `Any` and `AnyObject`.

### Any Example

class Subjects { var physics: String init(physics: String) { self.physics = physics } }

class Chemistry: Subjects { var equations: String init(physics: String, equations: String) { self.equations = equations super.init(physics: physics) } }

class Maths: Subjects { var formulae: String init(physics: String, formulae: String) { self.formulae = formulae super.init(physics: physics) } }

let sa = [ Chemistry(physics: "Solid State Physics", equations: "Hertz"), Maths(physics: "Fluid Dynamics", formulae: "Gigahertz"), Chemistry(physics: "Thermal Physics", equations: "Decibels"), Maths(physics: "Astrophysics", formulae: "Megahertz"), Maths(physics: "Differential Equations", formulae: "Cosine Series") ]

let samplechem = Chemistry(physics: "Solid State Physics", equations: "Hertz") print("Instance physics is: (samplechem.physics)") print("Instance equations: (samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Gigahertz") print("Instance physics is: (samplemaths.physics)") print("Instance formulas: (samplemaths.formulae)")

var chemCount = 0 var mathsCount = 0

for item in sa { // Conditional form of type casting if let show = item as? Chemistry { print("Chemistry subject is: '(show.physics)', (show.equations)") // Forced form } else if let example = item as? Maths { print("Math subject is: '(example.physics)', (example.formulae)") } }

// Array that can store any type exampleany var exampleany = Any

exampleany.append(12) exampleany.append(3.14159) exampleany.append("Any Example") exampleany.append(Chemistry(physics: "Solid State Physics", equations: "Megahertz"))

for item2 in exampleany { switch item2 { case let someInt as Int: print("Integer value is (someInt)")

```swift
switch item2 {
case let someDouble as Double where someDouble > 0:
    print("Pi value is \(someDouble)")
case let someString as String:
    print("\(someString)")
case let phy as Chemistry:
    print("Subject '\(phy.physics)', \(phy.equations)")
default:
    print("None")
}
}

The program execution output is:

Instance physics is: Solid State Physics
Instance equations: Hertz
Instance physics is: Fluid Dynamics
Instance formula is: Gigahertz
Chemistry subject is: 'Solid State Physics', Hertz
Math subject is: 'Fluid Dynamics', Gigahertz
Chemistry subject is: 'Thermal Physics', Decibels
Math subject is: 'Astrophysics', Megahertz
Math subject is: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Any instance
Subject 'Solid State Physics', Megahertz

AnyObject Instance

class Subjects {
    var physics: String
    init(physics: String) {
        self.physics = physics
    }
}

class Chemistry: Subjects {
    var equations: String
    init(physics: String, equations: String) {
        self.equations = equations
        super.init(physics: physics)
    }
}

class Maths: Subjects {
    var formulae: String
    init(physics: String, formulae: String) {
        self.formulae = formulae
        super.init(physics: physics)
    }
}

// Array of type [AnyObject]
let saprint: [AnyObject] = [
    Chemistry(physics: "Solid State Physics", equations: "Hertz"),
    Maths(physics: "Fluid Dynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermal Physics", equations: "Decibels"),
    Maths(physics: "Astrophysics", formulae: "Megahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")]

let samplechem = Chemistry(physics: "Solid State Physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equations: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Gigahertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formula is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in saprint {
    // Conditional form of type casting
    if let show = item as? Chemistry {
        print("Chemistry subject is: '\(show.physics)', \(show.equations)")
    // Forced form
    } else if let example = item as? Maths {
        print("Math subject is: '\(example.physics)', \(example.formulae)")
    }
}

var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any instance")
exampleany.append(Chemistry(physics: "Solid State Physics", equations: "Megahertz"))

for item2 in exampleany {
    switch item2 {
case let someInt as Int:
    print("Integer value is \(someInt)")
case let someDouble as Double where someDouble > 0:
    print("Pi value is \(someDouble)")
case let someString as String:
    print("\(someString)")
case let phy as Chemistry:
    print("Subject '\(phy.physics)', \(phy.equations)")
default:
    print("None")
}

The output of the above program is:

Instance physics is: Solid Physics
Instance equations: Hertz
Instance physics is: Fluid Dynamics
Instance formula is: GHz
Chemistry subject is: 'Solid Physics', Hertz
Mathematics subject is: 'Fluid Dynamics', GHz
Chemistry subject is: 'Thermal Physics', Decibel
Mathematics subject is: 'Astrophysics', GHz
Mathematics subject is: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Any instance
Subject 'Solid Physics', GHz

In a switch statement, use the forced type-casting operator (as, not as?) in a case to check and cast to a definite type.

❮ If Else Statement Swift Operators ❯