这是我的测试代码:
var myDict: [String: AnyObject] = ["k":"v"]
var a = myDict["k"]
var b = a as String
var c = myDict["k"] as String
这是我在 Xcode6-beta6 中的 Swift 游乐场:
根据类型推断的规则,在c
逻辑上不抱怨与不抱怨不矛盾b
吗?
这是我的测试代码:
var myDict: [String: AnyObject] = ["k":"v"]
var a = myDict["k"]
var b = a as String
var c = myDict["k"] as String
这是我在 Xcode6-beta6 中的 Swift 游乐场:
根据类型推断的规则,在c
逻辑上不抱怨与不抱怨不矛盾b
吗?
我相信这是一个错误。这里发生的部分事情是它String
不是一个对象。如果将第一行更改为:
var myDict: [String: Any] = ["k":"v"]
那么一切都很好。因此,鉴于字符串不是对象,将类型变量转换AnyObject?
为 aString
肯定会产生错误。而且,由于编译器已经决定它a
是类型AnyObject?
,它应该抱怨强制转换a
为String
.
请注意,如果您将最后一行更改为:
var c = myDict["k"] as NSString
错误消失了,支持了问题String
不是对象的概念。如果您将 aInt
作为数组中的值并尝试将其转换为Int
.
更新:
所以情节变厚了。如果您不import Foundation
导入或导入导入 Foundation 的内容,则会出现其他错误。无基础:
很明显,这与String
s 作为非对象和s 作为对象的双重性质以及在导入时使用s 作为sNSString
的能力有关。String
NSString
Foundation
Dictionary
这与具有两个下标重载的事实有关:
subscript (key: Key) -> Value?
subscript (i: DictionaryIndex<Key, Value>) -> (Key, Value) { get }
第一个是您熟悉的传递密钥的方法,它为您提供了一个可选的值;您可以使用它来设置键的值。
第二个不太常见。我相信DictionaryIndex
它是字典中的一种迭代器,您可以将其用作下标来直接获取该迭代器处的键值对。
当编译器找不到匹配的重载时(在这种情况下,第一个不匹配,因为它返回一个可选项,不能强制转换为 non-optional String
),它只是任意选择一个(嗯,这似乎是任意的无论如何对我来说)显示在错误中。在这个地方,它会选择你不认识的第二个。这就是为什么这个错误对你来说很奇怪。
这行得通。
var c = myDict["k"] as AnyObject! as String // "v"
要回答您的问题,Swift 抱怨的原因可能是您试图一次性完成这两个转换。请记住,该语句var a = myDict["k"]
已经包含一个隐式转换。隐含的转换是AnyObject?
,所以上面也可以这样工作:
var c = myDict["k"] as AnyObject? as String // "v"
"k"
请注意,如果未定义键,则上述内容将导致运行时错误。您可以nil
通过强制转换为String?
.