【问题标题】:Unwanted behaviour with optional binding evaluating optional(nil)可选绑定评估 optional(nil) 的不良行为
【发布时间】:2019-03-07 17:53:37
【问题描述】:

将 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.2 values[langCode!] as? TOptional(nil) 而在 Swift 4.1 上 values[langCode!] as? Tnil

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

是否有人在切换到 Swift4.2 时也遇到过这种情况? 有人有解释吗?还有解决办法吗?

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

谢谢

【问题讨论】:

  • @Hamish 在我看来就像一个真正的复制品 - 是吗?
  • @matt 可能——我只是对 OP 在他们的示例中说 TString 的事实感到有些困惑。如果是这种情况,那么Optional(nil) 的输出就没有多大意义。只有当T 类似于Any 时,它才真正有意义——如果是这样,那么是的,我会说这是一个骗局。
  • 你确定T 被推断为String 吗?不是String?吗?
  • 非常感谢,我认为我的问题是所描述的 [stackoverflow.com/questions/52446097/….. 是的,类型是 String?

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


【解决方案1】:

如果您没有更改代码并且它的行为有所不同,那么这可能是 Swift 中的一个错误。如果你能做一个小测试用例,你应该在https://bugs.swift.org 提交一个错误。

无论如何,听起来在 Swift 4.1 中,Swift 将类型 T 推导出为一些非 Optional 类型(例如 Int),而在 Swift 4.2 中,Swift 将 T 推导出为 Optional(例如 @987654326 @)。您可以通过添加以下语句来检查:

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

如果它在 Swift 4.1 下打印 Int(或其他),在 Swift 4.2 下打印 Optional<Int>,那就是问题所在。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 2019-01-12
      • 1970-01-01
      相关资源
      最近更新 更多