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

9

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

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

我不理解为什么as运算符将Bool转换为NSNumberas的文档给出了唯一的使用示例,即用于检查[Any]数组中元素的类型。这是来自文档的一个示例,也是我期望使用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个回答

15
as运算符可用于两种类型的转换:类型转换和桥接转换。类型转换可以将子类转换为超类(称为向上转型),也可以将超类向下转换为子类(仅在先将子类实例向上转换后才有效)。这就是您在Any数组示例中看到的内容。
但是,桥接转换是提供更容易的Foundation和Swift类之间互操作的机制。 NSNumber具有一个以Bool参数作为输入的init方法。您示例中的as运算符调用此初始化程序。
var b: Bool = true
var n: NSNumber = b as NSNumber

是“

的简写表示。

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

IntBool 都是 Swift 类型,因此桥接转换不适用于它们。

如需更多信息,请查看NSNumber 的文档


3

来自使用Cocoa框架(强调添加):

数字

Swift可以在NSNumber类和Swift数字类型之间进行桥接,包括IntDoubleBool

您可以通过使用as运算符将Swift数值转换为NSNumber对象。因为NSNumber可以包含多种不同的类型,所以在转换为Swift数字类型时必须使用as?运算符。


0
根据苹果文档,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

2
初始化和强制类型转换是不同的概念。你可以从整数初始化一个字符串:String(123),但你不能将一个整数强制类型转换为字符串:123 as String - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接