let number: Any = 10
switch number {
case 10 as Int:
print ("10")
default:
break
}
我只是想知道编译器采取什么步骤来解决常数的值?编译器是否先将数字转换为Int,然后将其与文字10进行比较?或者它将数字与10比较然后再投射?
代码基本上与以下内容相同:
let x: Int = 10
let number: Any = x
if let y = number as? Int, y == 10 {
print("10")
}
编译器检查值是否具有正确的类型(在这种情况下为Int
),然后转换它,然后将其与给定值(10
)进行比较。
没有其他方法可以实现,因为您无法真正比较不同类型的值。
您可以制作一些附加到被调用的各种函数的已检测数据类型,并打印有关它们的详细信息。这将有助于您深入了解事物的顺序:
struct InstrumentedInt: ExpressibleByIntegerLiteral, Equatable {
let value: Int
init(integerLiteral: Int) {
print("Initializing InstrumentedInt from \(integerLiteral)")
self.value = integerLiteral
}
static func == (lhs: InstrumentedInt, rhs: InstrumentedInt) -> Bool {
print("checking \(lhs) == \(rhs)")
return lhs.value == rhs.value
}
}
struct InstrumentedDouble: ExpressibleByFloatLiteral, Equatable {
let value: Double
init(integerLiteral: Int) {
print("Initializing InstrumentedInt from \(integerLiteral)")
self.value = Double(integerLiteral)
}
init(floatLiteral: Double) {
print("Initializing InstrumentedInt from \(floatLiteral)")
self.value = floatLiteral
}
static func == (lhs: InstrumentedDouble, rhs: InstrumentedDouble) -> Bool {
print("checking \(lhs) == \(rhs)")
return lhs.value == rhs.value
}
}
func instrumentedValueProducer(value: Any) -> Any {
print("Producing value \(value)")
return value
}
let instrumentedInt: InstrumentedInt = 10
let instrumentedDouble: InstrumentedDouble = 20.0
switch instrumentedValueProducer(value: instrumentedDouble) {
case 10 as InstrumentedInt: print("10 as InstrumentedInt")
case 20.0 as InstrumentedDouble: print("20 as InstrumnetedDouble")
default: print("default")
}
从10开始初始化InstrumentedInt
从20.0初始化InstrumentedInt
产生价值InstrumentedDouble(价值:20.0)
从20.0初始化InstrumentedInt
检查InstrumentedDouble(值:20.0)== InstrumentedDouble(值:20.0)
20作为InstrumentedDouble
令人惊讶的是,即使20
是第二种情况,编译器也不会将初始化程序InstrumentedInt.init(integerLiteral: 10)
用于比较。我想优化是聪明的,并创建一个查找表,完全跳过价值生成,不知何故。