"可选类型的值' 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?
接受,因为它的参数应该属于同一类型?那么,为什么我会收到此错误,我该如何解决?
答案 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;?