Swift 有什么区别吗?还有
我知道Swift 有什么区别吗?还有,swift,Swift,我知道Any表示任何对象的任何实例。但这是否包括可选值 我的情况是,我有数据: var data = form.values() //this returns [String: Any?] 我得到了一个函数,它接受了[String:Any] func sendRequest(data: [AnyHashable : Any]) 因此,当我将数据传递给此发送请求时,一切正常,但编译器会发出警告: Expression implicitly coerced from Any? to Any.
Any
表示任何对象的任何实例。但这是否包括可选值
我的情况是,我有数据
:
var data = form.values() //this returns [String: Any?]
我得到了一个函数,它接受了[String:Any]
func sendRequest(data: [AnyHashable : Any])
因此,当我将数据
传递给此发送请求
时,一切正常,但编译器会发出警告:
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.
所以,是的,我觉得完全迷失了方向。有人能给我解释一下发生了什么吗?
任何
都可以保存任何东西(是的,即使是可选的,但不推荐使用)Any?
保存一个可选值,该可选值的关联值可以是Any或nil
。Swift警告您不要将Any?
隐式转换为Any
,因为坦率地说,这是一个混乱。(很难知道Any
值包含可选值,但您必须强制转换它才能将其展开)。您可能应该考虑打开值,并创建一个新字典。
一般来说,具有可选值类型的字典是麻烦的/无意义的,因为将nil
赋值给字典用于从字典中删除项
如果您有一个返回[String:Any?]
的函数,并希望将其传递给另一个接受[String:Any]
的函数,我建议您通过展开值并丢弃值为nil
的条目来创建一个新字典
例如:
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)
在创建
newDict
时,我们可以利用这样一个事实,即当为值分配可选值时,会分配未包装的值。如果值为nil
,则不会创建条目。Any
包含任何内容(是的,即使是可选的,但不建议使用)Any?
保存一个可选值,该可选值的关联值可以是Any或nil
。Swift警告您不要将Any?
隐式转换为Any
,因为坦率地说,这是一个混乱。(很难知道Any
值包含可选值,但您必须强制转换它才能将其展开)。您可能应该考虑打开值,并创建一个新字典。
一般来说,具有可选值类型的字典是麻烦的/无意义的,因为将nil
赋值给字典用于从字典中删除项
如果您有一个返回[String:Any?]
的函数,并希望将其传递给另一个接受[String:Any]
的函数,我建议您通过展开值并丢弃值为nil
的条目来创建一个新字典
例如:
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)
在创建
newDict
时,我们可以利用这样一个事实,即当为值分配可选值时,会分配未包装的值。如果值为nil
,则不会创建条目。这是一个有趣的案例
根据:
Any类型表示任何类型的值,包括可选类型。
如果使用可选值,Swift将向您发出警告,其中
应为任何类型
sendRequest(data: data)
…您会收到一条警告,只是为了澄清您可能会意外通过期权:
从任何表达式隐式强制的表达式?对任何人
sendRequest(data: data as [String: Any])
sendRequest(data: data as! [String: Any])
…您会收到相同的警告:
从任何表达式隐式强制的表达式?对任何人
这一次的警告很奇怪,它警告你你正在做你真正想做的事情!我怀疑这可能是编译器的问题sendRequest(data: data as [String: Any])
sendRequest(data: data as! [String: Any])
…您将收到以下警告:
从[String:Any?]强制强制转换到[String:Any]始终成功
通常,要解决此警告,您应该改用类型转换(即删除!)。但是,正如我们所看到的,如果您也键入cast,则会收到警告sendRequest(data: vals as Any as! [String: Any])
这是一个有趣的案例 根据: Any类型表示任何类型的值,包括可选类型。 如果使用可选值,Swift将向您发出警告,其中 应为任何类型
sendRequest(data: data)
…您会收到一条警告,只是为了澄清您可能会意外通过期权:
从任何表达式隐式强制的表达式?对任何人
sendRequest(data: data as [String: Any])
sendRequest(data: data as! [String: Any])
…您会收到相同的警告:
从任何表达式隐式强制的表达式?对任何人
这一次的警告很奇怪,它警告你你正在做你真正想做的事情!我怀疑这可能是编译器的问题sendRequest(data: data as [String: Any])
sendRequest(data: data as! [String: Any])
…您将收到以下警告:
从[String:Any?]强制强制转换到[String:Any]始终成功
通常,要解决此警告,您应该改用类型转换(即删除!)。但是,正如我们所看到的,如果您也键入cast,则会收到警告sendRequest(data: vals as Any as! [String: Any])
请阅读。字典里的可选值无论如何都是毫无意义的。瓦迪安:你能更具体地说明你在那一章里说了什么吗