Bool with Foundation framework, can convert to AnyObject


(Zhao Xin) #1

We were told that Bool can't downcast to AnyObject in Swift. However, with
Foundation framework, we can.

do {

    let a:Bool = true

    let object:AnyObject = a as AnyObject

    object.dynamicType

    // __NSCFBoolean.Type

    let b:Bool = object as! Bool

    b // true

}

This feature works in some code automatically (like in a Dictionary), but
in some other codes(like in a function), you have to downcast it yourself.

do {

    var dictionary = Dictionary<String, AnyObject>()

    func update<T:AnyObject>(value:T, key:String) {

        dictionary.updateValue(value, forKey: key)

    }

    let aBool = true

    let key = "testBool"

    dictionary.updateValue(aBool, forKey: key)

    // works

    update(aBool, key: key)

    // doesn't work. cannot invoke 'update' with an argument list of type
'(Bool, key: String)'

    update(aBool as AnyObject, key:key)

    // works

}

My question: Is this normal? Should it all be automatic or not?

Zhaoxin


(Jordan Rose) #2

This is expected behavior: when you explicitly coerce (using ‘as’) or cast (using ‘as’ or ‘as!’), Bool can be converted to an NSNumber and from there up to AnyObject. Since NSNumber is part of Foundation, you need to have Foundation imported to do this.

We’re still deciding whether the conversion from Bool to NSNumber (and similar "bridging conversions") should be implicit or explicit. The conversion from NSNumber to Bool has been explicit for a while now.

Jordan

···

On May 25, 2016, at 02:11, zh ao via swift-users <swift-users@swift.org> wrote:

We were told that Bool can't downcast to AnyObject in Swift. However, with Foundation framework, we can.

do {
    let a:Bool = true
    let object:AnyObject = a as AnyObject
    object.dynamicType
    // __NSCFBoolean.Type
    let b:Bool = object as! Bool
    b // true
}

This feature works in some code automatically (like in a Dictionary), but in some other codes(like in a function), you have to downcast it yourself.

do {
    var dictionary = Dictionary<String, AnyObject>()
    
    func update<T:AnyObject>(value:T, key:String) {
        dictionary.updateValue(value, forKey: key)
    }
    
    let aBool = true
    let key = "testBool"
    
    dictionary.updateValue(aBool, forKey: key)
    // works
    
    update(aBool, key: key)
    // doesn't work. cannot invoke 'update' with an argument list of type '(Bool, key: String)'
    
    update(aBool as AnyObject, key:key)
    // works
}

My question: Is this normal? Should it all be automatic or not?


(Zhao Xin) #3

Thanks, Jordan.

Zhaoxin

···

On Thu, May 26, 2016 at 12:33 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On May 25, 2016, at 02:11, zh ao via swift-users <swift-users@swift.org> > wrote:

We were told that Bool can't downcast to AnyObject in Swift. However, with
Foundation framework, we can.

do {
    let a:Bool = true
    let object:AnyObject = a as AnyObject
    object.dynamicType
    // __NSCFBoolean.Type
    let b:Bool = object as! Bool
    b // true
}

This feature works in some code automatically (like in a Dictionary), but
in some other codes(like in a function), you have to downcast it yourself.

do {
    var dictionary = Dictionary<String, AnyObject>()

    func update<T:AnyObject>(value:T, key:String) {
        dictionary.updateValue(value, forKey: key)
    }

    let aBool = true
    let key = "testBool"

    dictionary.updateValue(aBool, forKey: key)
    // works

    update(aBool, key: key)
    // doesn't work. cannot invoke 'update' with an argument list of type
'(Bool, key: String)'

    update(aBool as AnyObject, key:key)
    // works

}

My question: Is this normal? Should it all be automatic or not?

This is expected behavior: when you explicitly coerce (using ‘as’) or cast
(using ‘as’ or ‘as!’), Bool can be converted to an NSNumber and from there
up to AnyObject. Since NSNumber is part of Foundation, you need to have
Foundation imported to do this.

We’re still deciding whether the conversion from Bool to NSNumber (and
similar "bridging conversions") should be implicit or explicit. The
conversion from NSNumber to Bool has been explicit for a while now.

Jordan