Соответствие литейному шаблону - PullRequest
0 голосов
/ 15 декабря 2018
let number: Any = 10

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

Мне просто интересно, какие шаги предпримет компилятор для определения значения константы число ?Компилятор сначала преобразует число в Int, а затем сравнивает его с литералом 10 ?Или он сравнивает число с 10 и затем разыгрывается?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Код в основном совпадает со следующим:

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

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

Компилятор проверяет, имеет ли значение правильный тип (в данном случае Int), затем приводит его к типу, а затем сравнивает его с заданнымзначение (10).

Нет другого способа, как это может быть, поскольку вы не можете реально сравнивать значения разных типов.

0 голосов
/ 15 декабря 2018

Вы можете создать некоторые инструментальные типы данных, которые подключаются к различным вызываемым функциям, и распечатывать подробности о них.Это поможет вам понять порядок вещей:

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")
}

Инициализация InstrumentedInt от 10

Инициализация InstrumentedInt от 20,0

Создание значения InstrumentedDouble (значение: 20.0)

Инициализация InstrumentedInt из 20.0

проверка InstrumentedDouble (значение: 20.0) == InstrumentedDouble (значение: 20.0)

20 as InstrumentedDouble

Удивительно, но хотя 20 является вторым случаем, компилятор не вызывает инициализатор InstrumentedInt.init(integerLiteral: 10) для использования для сравнения.Я полагаю, что оптимизация может быть разумной и создать справочную таблицу, которая каким-то образом полностью пропускает генерацию значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...