我知道Any
表示任何类型对象的任何实例。但这包括可选值吗?
我所拥有的是这种情况,我有data
:
var data = form.values() //this returns [String: Any?]
我得到了[String : Any]
func sendRequest(data: [AnyHashable : Any])
因此,当我将data
传递给此sendRequest
时,它很好,但编译器会发出警告:
Expression implicitly coerced from Any? to Any.
我明白为什么。我只是尝试将[String: Any?]
投射到[String: Any]
。当我这样做时:
var data = form.values() as! [String: Any]
我收到一条新的警告说:
Forced cast from [String: Any?] to [String: Any] always succeeds.
所以,我感到完全迷失了。有人可以向我解释发生了什么事吗?
答案 0 :(得分:0)
Any
拥有任何内容(是的,甚至 Optionals ,但不建议这样做)。 Any?
包含一个 Optional ,其关联值可以是任何值或nil
。 Swift警告你隐含地将Any?
转换为Any
,因为坦率地说这是一团糟。 (很难知道Any
值持有可选,但您必须将其强制转换才能展开它。您可能应该考虑展开值而不是创建新词典。
通常,对于值具有 Optional 类型的字典是麻烦/无意义的,因为nil
到字典的赋值用于从字典中删除项目。
如果你有一个函数返回[String : Any?]
并希望将它传递给另一个带[String : Any]
的函数,我建议你通过展开值并丢弃具有{nil
的函数来创建一个新的字典。 {1}}作为值。
例如:
let dict: [String : Any?] = ["name": "Fred", "age": 23, "nada": nil]
func foo(_ dict: [String : Any]) {
for (key, value) in dict {
print("\(key): \(value)")
}
}
var newDict = [String : Any]()
dict.forEach { key, value in newDict[key] = value }
foo(newDict)
name: Fred age: 23
在创建newDict
时,我们可以利用以下事实:在为值分配可选值时,会分配 unwrapped 值。如果值为nil
,则不会创建条目。
答案 1 :(得分:0)
这是一个有趣的案例。
根据The Swift Language Guide: Type Casting:
Any类型表示任何类型的值,包括可选类型。 如果您使用值为值的可选值,Swift会向您发出警告 任何类型的预期。
正如您所发现的,当您尝试将带有选项的字典传入sendRequest方法时...
sendRequest(data: data)
...你得到一个警告只是为了澄清你可能意外地传递了选项:
隐式强制表达Any?任何人。
如果您尝试输入它...
sendRequest(data: data as [String: Any])
...你得到同样的警告:
隐式强制表达Any?任何人。
这次警告很奇怪,警告你,你正在做你真正想做的事情!我怀疑这可能是编译器的问题。
如你所见,如果你试图强迫它......
sendRequest(data: data as! [String: Any])
...你收到这个警告:
从[String:Any?]到[String:Any]的强制转换总是成功的。
通常,要解决此警告,您可以使用类型转换(即删除!)。但是,正如我们已经看到的那样,如果您也输入了一个警告,则会收到警告。
你可以接受警告。删除警告的另一个冗长解决方案可能是先将类型转换为Any,然后强制转发为[String:Any]:
sendRequest(data: vals as Any as! [String: Any])