swift - 可选绑定评估 optional(nil) 的不良行为
问题描述
将 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? T
是nil
.
我检查了4.2 版的更改日志,但看不到可以解释该行为的内容,我还检查了 JSONSerialization 没有进行任何更改(用于序列化 json 文件)
有人在切换到 Swift4.2 时也经历过这种事情吗?有人有解释吗?和解决方法?
在这种代码中,使用可选绑定有什么好处?if (values[langCode!] != nil) {...
写而不是可选绑定会很糟糕吗?
谢谢
解决方案
如果您没有更改代码并且它的行为有所不同,那么这可能是 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>
,那就是问题所在。
推荐阅读
- sql - 显示两列,但其中一列与 SQL Server 中另一个表中的另一列联合
- decidable - 具有有限状态的给定 TM 是否可判定?
- python - 在 Python 中打印倒金字塔
- java - 当对象足够大时,如何告诉杰克逊序列化程序停止继续序列化和写入
- mongodb - 如何使用 mongoDB 中的聚合为数组中的每个元素添加求和字段
- python - Python ThreadPoolExecutor:没有按预期工作?
- flutter - 单引号中的flutter_html图像src标签
- generics - 从 num 扩展的泛型类型和从 int 到 double 类型转换的问题
- postgresql - JackRabbit OAK:在 postgresql 中生成空闲 DB 事务
- scala - Scala 编译器抛出:java.lang.IllegalAccessError: Class 'scala.tools.nsc.transform.patmat.PatternExpansion$ExtractorAlignment'