将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? T
是Optional(nil)
,在Swift 4.1中values[langCode!] as? T
是nil
。
我检查了version 4.2的变更日志,但看不到任何可以解释该行为的信息,还检查了JSONSerialization(用于序列化json文件)没有做任何更改
切换到Swift4.2时,有人也经历过这种事情吗? 有人有解释吗?并解决吗?
在这种代码中,使用可选绑定有什么好处?写if (values[langCode!] != nil) {...
而不是可选的绑定会很糟糕吗?
谢谢
答案 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