请考虑以下涉及nil合并运算符的 示例??:
let mysteryInc = ["Fred": "Jones", "Scooby-Doo": nil]
let lastname = mysteryInc["Scooby-Doo"] ?? "no last name"
print(lastname == nil) // true
Run Code Online (Sandbox Code Playgroud)
如最后一个print语句所示,nil合并运算符的结果是nil.
如果nil coalescing运算符应该解包一个Optional,为什么它会返回nil?
vac*_*ama 10
要查看此处发生了什么,请将字典指定为常量:
let name = mysteryInc["Scooby-Doo"]
print(type(of: name))
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)Optional<Optional<String>>
所以,name是一个双重可选,一个String??.
当应用nil coalescing运算符时,它会解包外部Optional并留下Optional<String>(aka String?).在问题的示例中,Swift将String文字"no last name"视为类型,String?以便??可以应用.
如果你检查你的价值,name你会发现它是Optional(nil).所有字典查找返回Optionals,因为密钥可能不存在(在这种情况下它们返回nil).在这种情况下,mysteryInc字典是类型的[String: String?].对应于该值"Scooby-Doo"是nil其然后被包裹成一个可选(因为字典的查找)成为Optional(nil).
最后,该值将Optional(nil)被解包??.因为Optional(nil) != nil,Swift解包Optional(nil)并返回nil而不是返回预期的"no last name".
这就是你如何nil从零合并算子中获得的.它解开了Optional ; 恰好nil是那个Optional的内部.
正如@LeoDabus在评论中指出的那样,处理这种情况的正确方法是在应用nil合并运算符之前有条件地转换名称:String
let lastname = mysteryInc["Scooby-Doo"] as? String ?? "no last name"
Run Code Online (Sandbox Code Playgroud)
实际上,最好避免将Optionals作为字典的值,因为@Sulthan引发了:
怎么mysteryInc["Fred"] = nil办?
分配nil到字典条目中删除从字典中的条目,所以mysteryInc["Fred"] = nil不会替换Optional("Jones")与nil,它消除了"Fred"完全的条目.要留下"Fred"字典并使其姓氏nil,您需要指定mysteryInc["Fred"] = Optional(nil)或mysteryInc.updateValue(nil, forKey: "Fred").
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |