2

将 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

if let即使 values[langCode!] 为“null”,这里也会执行该块。

一个区别是 swift 4.2values[langCode!] as? T是 anOptional(nil)而 Swift 4.1values[langCode!] as? Tnil.

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

有人在切换到 Swift4.2 时也经历过这种事情吗?有人有解释吗?和解决方法?

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

谢谢

4

2 回答 2

1

如果您没有更改代码并且它的行为有所不同,那么这可能是 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 和 Swift 4.2 下打印(或其他)Optional<Int>,那就是问题所在。

于 2018-10-02T15:17:02.693 回答
0

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

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

于 2018-10-05T08:37:06.633 回答