Нежелательное поведение с необязательной привязкой оценки необязательно (ноль) - PullRequest
0 голосов
/ 02 октября 2018

После обновления xCode до версии 10 (и swift 4.2) у меня странное поведение при необязательных привязках

Код приведен ниже, и речь идет о чтении файла json, T - универсальный тип(здесь String)

// Are there values for configName ?
if let values = cfg[configName] as? [String: Any] {

    print("0 - values[langCode!] = ", values[langCode!] ?? "null")
    print("1 - values[langCode!] as? T = ", values[langCode!] as? T)

    // is there a value for langCode ?
    if let value = values[langCode!] as? T {
        print("2 - value to return= ", value)
        return value
    } else {
        print("3 - Do something else ")
    }
}

В xCode 9.4.1 и Swift 4.1 у меня есть следующие журналы:

0 - values[langCode!] =  null
1 - values[langCode!] as? T =  nil
3 - Do something else 

Это то, что я хочу, values[langCode!] это nil и приведение также возвращает nil, поэтому выполняется блок else.

В xCode 10 со Swift 4.2 у меня есть следующие журналы:

0 - values[langCode!] =  null
1 - values[langCode!] as? T =  Optional(nil)
2 - value to return=  nil

Здесь if let блок выполняется, даже если значения [langCode!] равны «null».

Одно отличие состоит в том, что для swift 4.2 values[langCode!] as? T - это Optional(nil), а для Swift 4.1 values[langCode!] as? T - nil.

Я проверил журнал изменений для версии 4.2 и не смог увидеть что-то, что может объяснить это поведение, я также проверил, что в JSONSerialization не было внесено никаких изменений (используется для сериализации файла json)

Кто-то тоже испытывал подобные вещи при переходе на Swift4.2?У кого-нибудь есть объяснение?И как обойтись?

В таком коде, в чем преимущество использования необязательного связывания?было бы плохо написать if (values[langCode!] != nil) {... вместо необязательного связывания?

Спасибо

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Я отвечаю на мой вопрос, поскольку в комментариях был дан правильный ответ.

Разница, наблюдаемая между Swift4.1 и Swift4.2, связана с преднамеренным изменением.@ Хэмиш объясняет, что все в ответе сделано здесь: stackoverflow.com / q / 52446097/2976878

0 голосов
/ 02 октября 2018

Если вы не изменили код и он ведет себя по-другому, то это, вероятно, ошибка в Swift.Если вы можете сделать небольшой тестовый пример, вы должны сообщить об ошибке в https://bugs.swift.org.

В любом случае, это звучит как в Swift 4.1, Swift выводит тип T как некоторый не Optional тип (например, Int), а в Swift 4.2 Swift вместо этого выводит T как Optional (например, Int?).Вы можете проверить, добавив следующее утверждение:

print("Type T is bound to \(T.self)")

Если оно печатает Int (или что-то еще) в Swift 4.1 и Optional<Int> в Swift 4.2, то это проблема.

...