开关盒铸造模式匹配

问题描述 投票:1回答:2
let number: Any = 10

switch number {
    case 10 as Int:
       print ("10")
    default:
       break
}

我只是想知道编译器采取什么步骤来解决常数的值?编译器是否先将数字转换为Int,然后将其与文字10进行比较?或者它将数字与10比较然后再投射?

swift
2个回答
0
投票

代码基本上与以下内容相同:

let x: Int = 10
let number: Any = x

if let y = number as? Int, y == 10 {
   print("10")
}

编译器检查值是否具有正确的类型(在这种情况下为Int),然后转换它,然后将其与给定值(10)进行比较。

没有其他方法可以实现,因为您无法真正比​​较不同类型的值。


1
投票

您可以制作一些附加到被调用的各种函数的已检测数据类型,并打印有关它们的详细信息。这将有助于您深入了解事物的顺序:

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)用于比较。我想优化是聪明的,并创建一个查找表,完全跳过价值生成,不知何故。

© www.soinside.com 2019 - 2024. All rights reserved.