Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift casts Bool to NSNumber using 'as' operator

Tags:

casting

ios

swift

I found an interesting code in my project and I'm wondering how it even works. If I simplify it, in a playground it looks like this:

var b: Bool = true
var n: NSNumber = b as NSNumber

I don't understand why as operator casts Bool to NSNumber. Documentation for as gives the only example for using it, namely for checking a type of an element in the array of [Any]. That's an example from Docs and that's how I expected as to be used:

var things = [Any]()
for thing in things {
    switch thing {
    case 0 as Int:
    case 0 as Double:

I didn't expect as to do a real casting. Where can I read more about it? When I try similar code with Int instead of NSNumber, it doesn't compile:

var b: Bool = true
var n: Int = b as Int --> doesn't compile

So NSNumber seems to be a special case? I'm confused. Can anyone shed light on this?

like image 599
Anastasia Avatar asked Aug 10 '17 09:08

Anastasia


2 Answers

The as operator can be used for two types of casting. Type casting and bridge casting. Type casting can be used to convert subclasses to superclasses (called upcasting) or to downcast superclasses to subclasses (only works if first the subclass instance was upcasted). This is what you see in your example with the Any array.

Bridge casting is however a mechanisms provided for easier interoperability between Foundation and Swift classes. NSNumber has an init method that takes a Bool as its input argument. The as operator in your example calls this initializer, so

var b: Bool = true
var n: NSNumber = b as NSNumber

is just a shorthand notation for

var b:Bool = true
var n = NSNumber(value: b)

Int and Bool are both Swift types, so bridge casting doesn't work on them.

For more information, check the documentation of NSNumber.

like image 152
Dávid Pásztor Avatar answered Nov 12 '22 17:11

Dávid Pásztor


From Working with Cocoa Frameworks (emphasis added):

Numbers

Swift bridges between the NSNumber class and Swift numeric types, including Int, Double, and Bool.

You can create an NSNumber object by casting a Swift number value using the as operator. Because NSNumber can contain a variety of different types, you must use the as? operator when casting to a Swift number type.

like image 27
Martin R Avatar answered Nov 12 '22 16:11

Martin R