带有可选绑定的不需要的行为,评估为optional(nil)

时间:2018-10-02 15:04:07

标签: swift xcode10 ios12 swift4.2 optional-binding

将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块。

在带有Swift 4.2的xCode 10中,我有以下日志:

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

即使value [langCode!]为“ null”,也会执行if let块。

一个区别是,在Swift 4.2中values[langCode!] as? TOptional(nil),在Swift 4.1中values[langCode!] as? Tnil

我检查了version 4.2的变更日志,但看不到任何可以解释该行为的信息,还检查了JSONSerialization(用于序列化json文件)没有做任何更改

切换到Swift4.2时,有人也经历过这种事情吗? 有人有解释吗?并解决吗?

在这种代码中,使用可选绑定有什么好处?写if (values[langCode!] != nil) {...而不是可选的绑定会很糟糕吗?

谢谢

2 个答案:

答案 0 :(得分:1)

如果您没有更改代码,但其行为有所不同,则可能是Swift中的错误。如果您可以制作一个小的测试用例,则应在https://bugs.swift.org处提交一个错误。

无论如何,这听起来像是在Swift 4.1中,Swift推导类型T为某些非{Optional类型(例如Int),在Swift 4.2中,Swift推导T为{{ 1}}(例如Optional)。您可以通过添加以下语句进行检查:

Int?

如果在Swift 4.1下打印print("Type T is bound to \(T.self)") (或其他任何内容),在Swift 4.2下打印Int,那么就是问题所在。

答案 1 :(得分:0)

我回答了我的问题,因为评论中给出了正确的答案。

Swift4.1和Swift4.2之间观察到的差异是由于有意更改。 @Hamish解释了答案中的所有内容都在这里完成:stackoverflow.com/q/52446097/2976878