Type casting in swift : difference between is, as, as?, as!

What is the difference between is, as, as?, as! in swift? Well, lets check.

Apple doc says: Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy.

Type casting in Swift is implemented with the and operators. is used to check the type of a value whereas is used to cast a value to a different type.

Consider the following classs and two subclasses of named and .

Now create a constant array called with one class object and one class object. What do you think the type of this array created via type inference? It will be of type .

Swift’s type checker is able to deduce that and have a common superclass of , and so it infers a type of for the array.

The items stored in are still and instances behind the scenes. However, if you iterate over the contents of this array, the items you receive back are typed as , and not as or . In order to work with them as their native type, you need to check their type, or downcast them to a different type.

Checking Type

Use the type check operator () to check whether an instance is of a certain subclass type. The type check operator returns if the instance is of that subclass type and if it is not.

Consider the following code:

let livingBeingObj = livingBeingArray[0] // returns a LivingBeing object.

Let’s iterate the array objects over a loop.

for item in livingBeingArray {if item is Animal {print("item is of type Animal")// will get executed for first item} else if item is Human {print("item is of type Human")// will get executed for second item}}

Downcasting

Apple doc says: A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes. Where you believe this is the case, you can try to downcast to the subclass type with a type cast operator ( or ).

Let’s simplify this. Consider the array . We know that the first item is of type . Since array contains one object and one object, the type inference will decide the array type as . If we try to get any content from this array, it will return you an object of type In that case we can try to downcast it after fetching it form the array.

Difference between as? and as!

Downcasting can be done in two ways:

  • Conditional downcasting (as?).
  • Forced downcasting (as!).

The conditional form, , returns an optional value of the type you are trying to downcast to. The forced form, , attempts the downcast and force-unwraps the result as a single compound action.

Use the conditional form of the type cast operator () when you are not sure if the downcast will succeed. This form of the operator will always return an optional value, and the value will be if the downcast was not possible. This enables you to check for a successful downcast.

Use the forced form of the type cast operator () only when you are sure that the downcast will always succeed. This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type.

Here in the above scenario, since we know that the first object in the array is of type Animal, we can use Forced downcasting.

let animalObj = livingBeingArray[0] as! Animal //forced downcasting to Animallet humanObj = livingBeingArray[1] as! Human //forced downcasting to Human

But forced downcasting can fail if we try to downcast the first object to a and second object to an . In this case the result will be which a normal type cannot handle and the program will crash.

let animalObj = livingBeingArray[0] as! Human //error and crasheslet humanObj = livingBeingArray[1] as! Animal //error and crashes

In this scenario, where we are not sure if the casting succeeds, we should use the conditional downcasting .

let animalObj = livingBeingArray[0] as? Human //nil..animalObj is of Human? (optional Human which is the type which we tried to downcast to)let humanObj = livingBeingArray[1] as? Animal //nil..humanObj is of Animal? (optional Animal which is the type which we tried to downcast to)

But conditional downcasting of the correct type succeeds and returns the correct optional type that we are trying to downcast to.

let animalObj = livingBeingArray[0] as? Animal // success, returns Animal?let humanObj = livingBeingArray[1] as? Human // success, returns Human?

Upcasting

Upcasting from the base class object to its superclass is also possible. Let’s convert the created by forced downcasting back to the class.

let animalObj = livingBeingArray[0] as! Animal
let animalObjectAsLivingBeingObj = animalObj as LivingBeing

is of type .

Type Casting for Any and AnyObject

Swift provides two special types for working with nonspecific types:

  • can represent an instance of any type at all, including function types.
  • can represent an instance of any class type.
Source: Internet

The keyword ‘Any’ is used to represent an instance which belongs to any type including function types. Consider an array of type which can accept different types of values. We can use a switch statement to checl the type and do downcasting.

var groups = [Any]()
groups.append(1.0)
groups.append(1)
groups.append("string")

for item in groups {
switch item {
case let anInt as Int:
print("\(item) is an int")
case let aDouble as Double:
print("\(item) is a double")
case let aString as String:
print("\(item) is a string")

default:
print("dunno")
}
}

/*
1.0 is a double
1 is an int
string is a string
C11lldb_expr_13Pop (has 1 child) is a Genre
*/

Forced and conditional downcasting will not work in a

Using switch statement for type checking and downcasting :

for obj in livingBeingArray
{
switch obj {
case let animalObj as Animal:
print(“\(obj) is an animal”)
break
case let humanObj as Human:
print(“\(obj) is an human”)
break
default:
print(“unknown type”)
}
}

you may also use is operator for type checking.

for obj in livingBeingArray
{
switch obj {
case is Animal:
print(“\(obj) is an animal”)
break
case is Human:
print(“\(obj) is an human”)
break
default:
print(“unknown type”)
}
}

Source: AppleDocs

Enjoy!!

If you enjoyed reading this post, please share and recommend it so others can find it 💚💚💚💚💚💚 !!!!

iOS and tvOS developer, dreamer, photographer 🤨