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.
In short: == operator checks if their instance values are equal, "equal to" === operator checks if the references point the same instance, "identical to"
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.
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.
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.
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.
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With