English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Swift Type Casting

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

Type casting in Swift is implemented using the is and as operators, where is is used to detect 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 protocol.

Define a class hierarchy

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

The code is as follows:

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: "Hydrodynamics", formulae: "Gigahertz")
let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Example physics is: \(samplechem.physics)")
print("Example equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Hydrodynamics", formulae: "Gigahertz")
print("Example physics is: \(samplemaths.physics)")
print("Example formula is: \(samplemaths.formulae)")

The output result of the above program execution is:

The example physics is: Solid Physics
The example equation is: Hertz
The example physics is: Fluid Dynamics
The example formula is: Gigahertz

Check type

Type casting is used to detect whether the type of an example belongs to a specific example type.

You can use it on the class and subclass hierarchy to check the type of a specific class example and convert the type of this class example to another type in the hierarchy.

Type checking uses is keyword.

operator is To check if an example belongs to a specific subtype. If the example belongs to that subtype, 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: "Hydrodynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermophysics", equations: "Decibels"),
    Maths(physics: "Astronomy", formulae: "Gigahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Example physics is: \(samplechem.physics)")
print("Example equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Hydrodynamics", formulae: "Gigahertz")
print("Example physics is: \(samplemaths.physics)")
print("Example formula is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
    // If an example is of the Chemistry type, return true; otherwise, return false.
    if item is Chemistry {
        ++chemCount
    } else if item is Maths {
        ++mathsCount
    }
}
print("Chemistry subjects include \(chemCount) topics, Mathematics includes \(mathsCount) topics")

The output result of the above program execution is:

The example physics is: Solid Physics
The example equation is: Hertz
The example physics is: Fluid Dynamics
The example formula is: Gigahertz
The subjects of chemistry include 2 topics, mathematics includes 3 topics

Downcasting

Downcasting, using type conversion operators (as? or as!)

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

Use forced form (as!) only when you are sure that downcasting will always succeed. When you try to downcast to an incorrect type, forced type conversion 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 Physics", equations: "Hertz"),
    Maths(physics: "Hydrodynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermophysics", equations: "Decibels"),
    Maths(physics: "Astronomy", formulae: "Gigahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Example physics is: \(samplechem.physics)")
print("Example equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Hydrodynamics", formulae: "Gigahertz")
print("Example physics is: \(samplemaths.physics)")
print("Example formula is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
    // Conditional form of type conversion
    if let show = item as? Chemistry {
        print("Chemistry topic is: '\(show.physics)', \(show.equations)")
        // Force form
    } else if let example = item as? Maths {
        print("Mathematics topic is: '\(example.physics)', \(example.formulae)")
    }
}

The output result of the above program execution is:

The example physics is: Solid Physics
The example equation is: Hertz
The example physics is: Fluid Dynamics
The example formula is: Gigahertz
The chemical topic is: 'Solid Physics', Hertz
The mathematical topic is: 'Fluid Dynamics', Gigahertz
The chemical topic is: 'Thermophysics', Decibels
The mathematical topic is: 'Astronomy', Megahertz
The mathematical topic is: 'Differential Equations', Cosine Series

Type conversion of Any and AnyObject

Swift provides two special type aliases for uncertain types:

  • AnyObjectCan represent an example of any class type.
  • AnyCan represent any type, including function types.

Note:
should only be used when you explicitly need its behavior and functionalityAnyandAnyObjectIt is always better to use explicit types in your code as expected.

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 Physics", equations: "Hertz"),
    Maths(physics: "Hydrodynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermophysics", equations: "Decibels"),
    Maths(physics: "Astronomy", formulae: "Gigahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Example physics is: \(samplechem.physics)")
print("Example equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Hydrodynamics", formulae: "Gigahertz")
print("Example physics is: \(samplemaths.physics)")
print("Example formula is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
    // Conditional form of type conversion
    if let show = item as? Chemistry {
        print("Chemistry topic is: '\(show.physics)', \(show.equations)")
        // Force form
    } else if let example = item as? Maths {
        print("Mathematics topic is: '\(example.physics)', \(example.formulae)")
    }
}
// Can store an array of Any type exampleany
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any Example")
exampleany.append(Chemistry(physics: "Solid Physics", equations: "Gigahertz"))
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("Topic '\(phy.physics)', \(phy.equations)")
    default:
        print("None")
    }
}

The output result of the above program execution is:

The example physics is: Solid Physics
The example equation is: Hertz
The example physics is: Fluid Dynamics
The example formula is: Gigahertz
The chemical topic is: 'Solid Physics', Hertz
The mathematical topic is: 'Fluid Dynamics', Gigahertz
The chemical topic is: 'Thermophysics', Decibels
The mathematical topic is: 'Astronomy', Megahertz
The mathematical topic is: 'Differential Equations', Cosine Series
Integer Value is 12
Pi Value is 3.14159
Any Example
Topic 'Solid Physics', Megahertz

An example of AnyObject

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 [AnyObject] type
let saprint: [AnyObject] = [
    Chemistry(physics: "Solid Physics", equations: "Hertz"),
    Maths(physics: "Hydrodynamics", formulae: "Gigahertz"),
    Chemistry(physics: "Thermophysics", equations: "Decibels"),
    Maths(physics: "Astronomy", formulae: "Gigahertz"),
    Maths(physics: "Differential Equations", formulae: "Cosine Series")
let samplechem = Chemistry(physics: "Solid Physics", equations: "Hertz")
print("Example physics is: \(samplechem.physics)")
print("Example equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Hydrodynamics", formulae: "Gigahertz")
print("Example physics is: \(samplemaths.physics)")
print("Example formula is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in saprint {
    // Conditional form of type conversion
    if let show = item as? Chemistry {
        print("Chemistry topic is: '\(show.physics)', \(show.equations)")
        // Force form
    } else if let example = item as? Maths {
        print("Mathematics topic is: '\(example.physics)', \(example.formulae)")
    }
}
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any Example")
exampleany.append(Chemistry(physics: "Solid Physics", equations: "Gigahertz"))
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("Topic '\(phy.physics)', \(phy.equations)")
    default:
        print("None")
    }
}

The output result of the above program execution is:

The example physics is: Solid Physics
The example equation is: Hertz
The example physics is: Fluid Dynamics
The example formula is: Gigahertz
The chemical topic is: 'Solid Physics', Hertz
The mathematical topic is: 'Fluid Dynamics', Gigahertz
The chemical topic is: 'Thermophysics', Decibels
The mathematical topic is: 'Astronomy', Megahertz
The mathematical topic is: 'Differential Equations', Cosine Series
Integer Value is 12
Pi Value is 3.14159
Any Example
Topic 'Solid Physics', Megahertz

Use the forced type casting operator (as, not as?) in a case of a switch statement to check and convert to an explicit type.