Swift使用'as'运算符将Bool强制转换为NSNumber

时间:2017-08-10 09:44:34

标签: ios swift casting

我在项目中发现了一个有趣的代码,我想知道它是如何工作的。如果我简化它,在游乐场看起来像这样:

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

我不明白为什么as运算符会将Bool强制转换为NSNumberas的文档提供了使用它的唯一示例,即检查[Any]数组中元素的类型。这是Docs的一个例子,这就是我期望as使用的方式:

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

我没想到as会做真正的演员。我在哪里可以阅读更多相关信息? 当我尝试使用Int代替NSNumber的类似代码时,它不会编译:

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

所以NSNumber似乎是一个特例?我糊涂了。有人能说清楚这个吗?

3 个答案:

答案 0 :(得分:7)

as运算符可用于两种类型的转换。型铸造和桥梁铸造。类型转换可用于将子类转换为超类(称为upcasting)或向下转换超类转换为子类(仅在首次提升子类实例时才有效)。这是您在示例中看到的Any数组。

然而,桥接转换是一种机制,可以提高FoundationSwift类之间的互操作性。 NSNumber有一个init方法,它以Bool作为输入参数。示例中的as运算符调用此初始值设定项,因此

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

只是

的简写符号
var b:Bool = true
var n = NSNumber(value: b)

IntBool都是Swift类型,因此网桥投射不适用于它们。

有关详细信息,请查看documentation of NSNumber

答案 1 :(得分:2)

来自Working with Cocoa Frameworks(强调补充):

  

数字

     

NSNumber类和Swift数字类型之间的快速桥梁,包括IntDoubleBool

     

您可以使用NSNumber运算符强制转换Swift数值来创建as对象。因为NSNumber可以包含各种不同的类型,所以在转换为Swift数字类型时必须使用as?运算符。

答案 2 :(得分:0)

根据Apple文档, NSNumber 可以初始化,具有以下数据类型,因此也可以类型化: -

open class NSNumber : NSValue {

        public init?(coder aDecoder: NSCoder)

        public init(value: Int8)

        public init(value: UInt8)

        public init(value: Int16)

        public init(value: UInt16)

        public init(value: Int32)

        public init(value: UInt32)


        public init(value: Int64)

        public init(value: UInt64)

        public init(value: Float)

        public init(value: Double)

        public init(value: Bool)

        @available(iOS 2.0, *)
        public init(value: Int)

        @available(iOS 2.0, *)
        public init(value: UInt)


        open var int8Value: Int8 { get }

        open var uint8Value: UInt8 { get }

        open var int16Value: Int16 { get }

        open var uint16Value: UInt16 { get }

        open var int32Value: Int32 { get }

        open var uint32Value: UInt32 { get }


        open var int64Value: Int64 { get }

        open var uint64Value: UInt64 { get }

        open var floatValue: Float { get }

        open var doubleValue: Double { get }

        open var boolValue: Bool { get }

        @available(iOS 2.0, *)
        open var intValue: Int { get }

        @available(iOS 2.0, *)
        open var uintValue: UInt { get }


        open var stringValue: String { get }


        open func compare(_ otherNumber: NSNumber) -> ComparisonResult


        open func isEqual(to number: NSNumber) -> Bool


        open func description(withLocale locale: Any?) -> String
    }

所以以下所有例子都是正确的: -

        let intValue : Int = 2
        let floatValue : Float = 2.0
        let boolValue : Bool = true
        let doubleValue : Double = 2

        let x = intValue as NSNumber
        let y = floatValue as NSNumber
        let z = boolValue as NSNumber
        let a = doubleValue as NSNumber