我在项目中发现了一个有趣的代码,我想知道它是如何工作的。如果我简化它,在游乐场看起来像这样:
var b: Bool = true
var n: NSNumber = b as NSNumber
我不明白为什么as
运算符会将Bool
强制转换为NSNumber
。 as
的文档提供了使用它的唯一示例,即检查[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
似乎是一个特例?我糊涂了。有人能说清楚这个吗?
答案 0 :(得分:7)
as
运算符可用于两种类型的转换。型铸造和桥梁铸造。类型转换可用于将子类转换为超类(称为upcasting)或向下转换超类转换为子类(仅在首次提升子类实例时才有效)。这是您在示例中看到的Any
数组。
然而,桥接转换是一种机制,可以提高Foundation
和Swift
类之间的互操作性。 NSNumber
有一个init
方法,它以Bool
作为输入参数。示例中的as
运算符调用此初始值设定项,因此
var b: Bool = true
var n: NSNumber = b as NSNumber
只是
的简写符号var b:Bool = true
var n = NSNumber(value: b)
Int
和Bool
都是Swift
类型,因此网桥投射不适用于它们。
有关详细信息,请查看documentation of NSNumber。
答案 1 :(得分:2)
来自Working with Cocoa Frameworks(强调补充):
数字的
NSNumber
类和Swift数字类型之间的快速桥梁,包括Int
,Double
和Bool
。您可以使用
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