let number: Any = 10
switch number {
case 10 as Int:
print ("10")
default:
break
}
我只是想知道编译器采取什么步骤来解析常数 number 的值?编译器是否先将 number 强制转换为Int,然后将其与文字 10 进行比较?还是将数字与 10 进行比较,然后进行投射?
答案 0 :(得分:1)
您可以使某些检测到的数据类型挂接到调用的各种函数中,并打印有关它们的详细信息。这将帮助您深入了解事物的顺序:
Select concat(f1, ' - ', f2) as combinedData . . .
从10开始初始化InstrumentedInt
从20.0初始化InstrumentedInt
产值InstrumentedDouble(值20.0)
从20.0初始化InstrumentedInt
检查InstrumentedDouble(value:20.0)== InstrumentedDouble(value:20.0)
20为InstrumentedDouble
令人惊讶的是,即使第二种情况是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")
}
,编译器也不会调用初始化程序20
进行比较。我猜想优化可以很聪明,并且可以创建一个查找表,从而完全跳过生成值的过程。
答案 1 :(得分:0)
代码基本上与以下代码相同:
let x: Int = 10
let number: Any = x
if let y = number as? Int, y == 10 {
print("10")
}
编译器检查值是否具有正确的类型(在这种情况下为Int
),然后将其强制转换,然后将其与给定的值(10
)进行比较。
因为您无法真正比较不同类型的值,所以别无选择。