可选类型 'String??' 未展开
Optional Type 'String??' Not Unwrapped
"Value of optional type 'String??' not unwrapped; did you mean to use '!' or '?'?"-
我今天遇到了这个奇怪的编译器错误,由于 String
之后的 两个 问号,这完全令人困惑。
我有一个类型为 [String : String?]
的字典 s
和一个接受所有参数为 String?
的函数。具体来说(来自 5813 的 将用户选择的信息复制到字典中),我有以下详细版本:
func combine(firstname: String?, lastname: String?) {...}
var text = combine(s["kABPersonFirstNameProperty"], lastname: s["kABPersonLastNameProperty"])
我在第二行收到错误,我想知道为什么会这样。如果 s
中的值是 String?
类型,那不应该被 combine()
接受,因为它的参数应该是同一类型吗?那么,为什么我会收到此错误,我该如何解决呢?
它曾经是可选的,因为您的字典值是可选的。它又是可选的,因为 dictionary[key] returns 是可选的。所以你需要解包两次。
在操场上试试这个以了解问题(并查看可能的解决方案):
let oos: String?? = "Hello"
print(oos)
if let os = oos { // Make String?
print(os)
if let s = os { // Make ordinary String
print(s)
}
}
打印:
Optional(Optional("Hello"))
Optional("Hello")
Hello
但是你也可以使用 if let 以外的其他方式来解包。例如:
print(oos! ?? "n/a")
将强制解包一次然后打印内部字符串或 n/a 以防 nil...
Dictionary<T1, T2>[key]
returns T2?
。这是 return 零,以防密钥不存在。
所以如果 T2 是 String?
, s[key]
returns String??
您不能将 String??
作为 String?
你也可以像这样调用来解包并准备不存在的密钥
var text = combine(s["kABPersonFirstNameProperty"] ?? nil, lastname: s["kABPersonLastNameProperty"] ?? nil)
顺便说一下,下面的代码不会将值设置为 nil,而是会从字典中删除整个条目
s[key] = nil
如果您希望值为 nil 而不是删除条目,则必须这样做
s[key] = nil as String?
也许最简单的解决方案是使字典包含 String
而不是 String?
。那么您就不会遇到其他解决方案中描述的展开问题。
或者您真的必须存储 String?
类型吗?
您想区分 'key exists but holds nil' 和 'key does not exist' 吗?
"Value of optional type 'String??' not unwrapped; did you mean to use '!' or '?'?"-
我今天遇到了这个奇怪的编译器错误,由于 String
之后的 两个 问号,这完全令人困惑。
我有一个类型为 [String : String?]
的字典 s
和一个接受所有参数为 String?
的函数。具体来说(来自 5813 的
func combine(firstname: String?, lastname: String?) {...}
var text = combine(s["kABPersonFirstNameProperty"], lastname: s["kABPersonLastNameProperty"])
我在第二行收到错误,我想知道为什么会这样。如果 s
中的值是 String?
类型,那不应该被 combine()
接受,因为它的参数应该是同一类型吗?那么,为什么我会收到此错误,我该如何解决呢?
它曾经是可选的,因为您的字典值是可选的。它又是可选的,因为 dictionary[key] returns 是可选的。所以你需要解包两次。
在操场上试试这个以了解问题(并查看可能的解决方案):
let oos: String?? = "Hello"
print(oos)
if let os = oos { // Make String?
print(os)
if let s = os { // Make ordinary String
print(s)
}
}
打印:
Optional(Optional("Hello"))
Optional("Hello")
Hello
但是你也可以使用 if let 以外的其他方式来解包。例如:
print(oos! ?? "n/a")
将强制解包一次然后打印内部字符串或 n/a 以防 nil...
Dictionary<T1, T2>[key]
returns T2?
。这是 return 零,以防密钥不存在。
所以如果 T2 是 String?
, s[key]
returns String??
您不能将 String??
作为 String?
你也可以像这样调用来解包并准备不存在的密钥
var text = combine(s["kABPersonFirstNameProperty"] ?? nil, lastname: s["kABPersonLastNameProperty"] ?? nil)
顺便说一下,下面的代码不会将值设置为 nil,而是会从字典中删除整个条目
s[key] = nil
如果您希望值为 nil 而不是删除条目,则必须这样做
s[key] = nil as String?
也许最简单的解决方案是使字典包含 String
而不是 String?
。那么您就不会遇到其他解决方案中描述的展开问题。
或者您真的必须存储 String?
类型吗?
您想区分 'key exists but holds nil' 和 'key does not exist' 吗?