Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between 'is' and 'as' keyword in Swift

Tags:

swift

I'm new to Swift and is trying to learn the concept of keyword 'is' and 'as'. I understand 'is' is the type check operator (to check if a variable is of certain subclass) while the 'as' is the type cast operator (to downcast a variable to its subclass).

However, my question is if there are areas where those two keywords can be used interchangeably and if there are areas that they can't.

like image 490
Thor Avatar asked Feb 14 '16 05:02

Thor


People also ask

What is == and === in Swift?

In short: == operator checks if their instance values are equal, "equal to" === operator checks if the references point the same instance, "identical to"

What does ~= mean in Swift?

The expression represented by the expression pattern is compared with the value of an input expression using the Swift standard library ~= operator. The matches succeeds if the ~= operator returns true . By default, the ~= operator compares two values of the same type using the == operator.

What is Downcasting in Swift?

Downcasting. Downcasting is used to reconvert the object of superclass back to their subclasses. We can think of it as moving down the hierarchy. Like upcasting down casting can only be done within the same hierarchies.

What is optionals in Swift?

An optional acts as a container for a value of a particular type. The container holds a value or it doesn't. Type safety is a cornerstone of the Swift language. As a result, variables and constants need to be initialized before they can be accessed.


2 Answers

The following are basically identical:

if let _ = myObject as? SomeClass ...
if myObject is SomeClass ...

The only real difference is that as converts it to the resultant class for you to then use. In the code above I used the placeholder "_", which means I don't really want the result. You will find you don't use is as much in Swift as you do in other languages because of the if let construct. For example:

if let mySomeClass = myObject as? SomeClass {
    // Now I know mySomeClass is a SomeClass so I can use it.
}
like image 153
Michael Avatar answered Nov 16 '22 02:11

Michael


As a newbie to Swift from Objective C background, here is my common way to write the casting, using similar structure of instanceof in Objective-C and followed by a casting:

if (someObject is someClass) {
  (someObject as! someClass).someFunc()
}

or 

if (someObject is someClass) {
  let anObject = (someObject as! someClass)
  anObject.someFunc()
}

It can be simplified with Optional Binding:

if let anObject = someObject as? someClass {
    anObject.someFunc()
}

Some prefer to reuse the object name (not introducing new names to code):

if let someObject = someObject as? someClass {
    someObject.someFunc()
}

If the body of if-let-as? is just one function call, it can be further simplified with Optional Chaining:

(someObject as? someClass)?.someFunc()

When I first migrate from Obj-C to Swift, I let the Xcode compiler to suggest correction of my syntax error regarding optional code. I usually end up with this:

(someObject as! someClass).someFunc()

However, when I study Apple's "The Swift Programming Language (Swift 3.1)" eBook, I found this can be a trap. Here is the part of text from section "Type-Casting Operators":

The as! operator performs a forced cast of the expression to the specified type. The as! operator returns a value of the specified type, not an optional type. If the cast fails, a runtime error is raised. The behavior of x as! T is the same as the behavior of (x as? T)!.

So, when someObject isn't someClass, the runtime error will crash my app.

like image 26
John Pang Avatar answered Nov 16 '22 03:11

John Pang