这是我的测试代码:
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
抱怨不抱怨?
答案 0 :(得分:2)
我相信这是一个错误。这里发生的部分原因是String
不是一个对象。如果您将第一行更改为:
var myDict: [String: Any] = ["k":"v"]
然后一切都很好。因此,如果字符串不是对象,则将AnyObject?
类型的变量强制转换为String
应该会产生错误。并且,由于编译器已经确定a
属于AnyObject?
类型,因此应该抱怨将a
投射到String
。
请注意,如果您将最后一行更改为:
var c = myDict["k"] as NSString
错误消失了,支持这个问题是String
不是一个对象。如果您将Int
作为数组中的值并尝试将其转换为Int
,则会得到相同的投诉。
<强>更新强>:
因此情节变浓。如果您没有import Foundation
或导入导入Foundation的内容,则会出现其他错误。没有基金会:
很明显,其中一些与String
s作为非对象和NSString
作为对象的双重性质以及使用String
作为{{1}的能力有关导入NSString
时的情况。
答案 1 :(得分:1)
这与Dictionary
两个下标重载的事实有关:
subscript (key: Key) -> Value?
subscript (i: DictionaryIndex<Key, Value>) -> (Key, Value) { get }
第一个是熟悉的,你传递一个键,它给你一个可选的值;您可以使用它来设置键的值。
第二个不太常见。我相信DictionaryIndex
是字典中的一种迭代器,你可以用它作为下标来直接获取该迭代器的键值对。
当编译器找不到匹配的重载时(在这种情况下,第一个不匹配,因为它返回一个可选的,不能转换为非可选的String
),它只是随意挑选一个(好吧,无论如何,这对我来说似乎是武断的)来显示错误。在这个地方,它会选择你不认识的第二个。这就是为什么这个错误对你来说很奇怪。
答案 2 :(得分:0)
这很有效。
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?
。