任何区别?和任何

时间:2017-10-08 10:50:03

标签: swift

我知道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. 

所以,我感到完全迷失了。有人可以向我解释发生了什么事吗?

2 个答案:

答案 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会向您发出警告   任何类型的预期。

  1. 正如您所发现的,当您尝试将带有选项的字典传入sendRequest方法时...

    sendRequest(data: data) 
    

    ...你得到一个警告只是为了澄清你可能意外地传递了选项:

      

    隐式强制表达Any?任何人。

  2. 如果您尝试输入它...

    sendRequest(data: data as [String: Any]) 
    

    ...你得到同样的警告:

      

    隐式强制表达Any?任何人。

    这次警告很奇怪,警告你,你正在做你真正想做的事情!我怀疑这可能是编译器的问题。

  3. 如你所见,如果你试图强迫它......

    sendRequest(data: data as! [String: Any]) 
    

    ...你收到这个警告:

      

    从[String:Any?]到[String:Any]的强制转换总是成功的。

    通常,要解决此警告,您可以使用类型转换(即删除!)。但是,正如我们已经看到的那样,如果您也输入了一个警告,则会收到警告。

  4. 你可以接受警告。删除警告的另一个冗长解决方案可能是先将类型转换为Any,然后强制转发为[String:Any]:

    sendRequest(data: vals as Any as! [String: Any])