可选类型' String ??'没有打开包装

时间:2015-08-07 03:20:17

标签: ios swift dictionary optional optional-parameters

"可选类型的值' String ??'没有打开;你的意思是使用'!'或'?'?" -

我今天遇到了这个奇怪的编译器错误,由于function MyDirective($compile) { return { restrict: "AE", templateUrl: "/path", link: (scope, element, attributes) => { // Add your directives $compile(element.contents())(scope); } }; }之后的两个问号,这完全令人困惑。

我有一个类型为String的字典s,以及一个接受所有参数为[String : String?]的函数。具体来说(从5813' s method将用户选择的信息复制到字典中),我有以下详细说明的版本:

String?

我在第二行收到错误,我想知道为什么会这样。如果func combine(firstname: String?, lastname: String?) {...} var text = combine(s["kABPersonFirstNameProperty"], lastname: s["kABPersonLastNameProperty"]) 中的值属于s类型,则不应由String?接受,因为它的参数应该属于同一类型?那么,为什么我会收到此错误,我该如何解决?

3 个答案:

答案 0 :(得分:3)

Dictionary<T1, T2>[key]返回T2?。如果密钥不存在,则返回nil。

因此,如果T2为String?,则s[key]会返回String?? 您无法将String??作为String?

传递

您可以像这样打电话来打开并准备不存在的密钥

var text = combine(s["kABPersonFirstNameProperty"] ?? nil, lastname: s["kABPersonLastNameProperty"] ?? nil)

顺便说一下,下面的代码不会将值设置为nil,而是从字典中删除整个条目

s[key] = nil

如果您希望值为nil而不是删除条目,则必须执行此操作

s[key] = nil as String?

答案 1 :(得分:2)

它曾经是可选的,因为您的字典值是可选的。它又是可选的,因为dictionary [key]返回可选。所以你需要打开两次。

在操场上试一试以了解问题(并查看可能的解决方案):

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

但你也可以使用其他方式,而不是让它解开。例如:

 print(oos! ?? "n/a")

强行打开一次,然后打印内部字符串或n / a,如果没有...

答案 2 :(得分:0)

也许最简单的解决方案是让词典保持String而不是String?。然后,您不会遇到其他解决方案中描述的解缠问题。

或者你真的必须存储String?类型吗? 你想要区分关键存在但是持有nil&#39;和&#39;密钥不存在&#39;?