Swift 下标错误
Swift Subscript Error
我相信它与可选项有关,但我正在安全地解包 sourceURL,所以我仍然不确定错误在哪里!我正在尝试访问 JSON 对象数组的字典值。
但是,我仍然收到“找不到接受所提供参数的 'subscript' 的重载。
看起来很简单,但我就是想不通!
var dictTemp: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &localError) as? NSDictionary
var finalURL: String
// error line below
if let sourceURL = dictTemp[0]["source"]["sourceUrl"] as? NSString {
finalURL = sourceURL as String
}
从 Swift 访问的 NSDictionary 是一个有趣的野兽。
只要Swift只知道某物是NSDictionary(不是更具体的[Key: Value]
Swift风格的字典),你只能检索AnyObject?
s
let dictTemp: NSDictionary = // from somewhere...
let step1 = dictTemp[0] // step1 is an AnyObject?
但是,由于您已经导入了 Foundation,您可以继续使用适用于 AnyObject
的神奇下标运算符,并检查它是否是字典:
let step2 = step1?["source"] // step2 is any AnyObject??
这里是有趣的地方,因为
- 如果
step1
是一个包含 "source" 键的字典,step2
将是对应的值。
- 如果
step1
是字典 而没有 "source" 键,step2
将是nil
— 特别是 AnyObject??.Some(AnyObject?.None)
.
- 如果
step1
为 nil(原始字典没有 0 作为键),或者不是字典(它有一个 0 键和其他类型的值),则 step2
将是 nil
— 特别是 AnyObject??.None
.
(后两种情况的区别基本上不重要,您不必担心,但如果您有兴趣可以使用dump
查看)。
当然,我们可以再次应用相同的原理:
let step3 = step2??["sourceUrl"] // step3 is AnyObject?? again
现在,将它们全部绑定到一个 if
:
if let url = dictTemp[0]?["source"]??["sourceUrl"] as? String {
// do something with url...
}
警告
这种类型的语法可能很危险,因为它同时适用于数组和字典。在这些情况下您会期望什么?
let dict: NSDictionary = [0: ["source": [3: "result"]]]
dict[0]?["source"]??[3] // returns nil (surprise!)
dict[0]?["source"]??[3 as NSNumber] // returns "result"
let dict2: NSDictionary = [0: ["source": [8, 7, 6, 5, 4]]]
dict2[0]?["source"]??[3] // returns 5
dict2[0]?["source"]??[3 as NSNumber] // returns nil (surprise!)
我相信它与可选项有关,但我正在安全地解包 sourceURL,所以我仍然不确定错误在哪里!我正在尝试访问 JSON 对象数组的字典值。
但是,我仍然收到“找不到接受所提供参数的 'subscript' 的重载。
看起来很简单,但我就是想不通!
var dictTemp: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &localError) as? NSDictionary
var finalURL: String
// error line below
if let sourceURL = dictTemp[0]["source"]["sourceUrl"] as? NSString {
finalURL = sourceURL as String
}
从 Swift 访问的 NSDictionary 是一个有趣的野兽。
只要Swift只知道某物是NSDictionary(不是更具体的[Key: Value]
Swift风格的字典),你只能检索AnyObject?
s
let dictTemp: NSDictionary = // from somewhere...
let step1 = dictTemp[0] // step1 is an AnyObject?
但是,由于您已经导入了 Foundation,您可以继续使用适用于 AnyObject
的神奇下标运算符,并检查它是否是字典:
let step2 = step1?["source"] // step2 is any AnyObject??
这里是有趣的地方,因为
- 如果
step1
是一个包含 "source" 键的字典,step2
将是对应的值。 - 如果
step1
是字典 而没有 "source" 键,step2
将是nil
— 特别是AnyObject??.Some(AnyObject?.None)
. - 如果
step1
为 nil(原始字典没有 0 作为键),或者不是字典(它有一个 0 键和其他类型的值),则step2
将是nil
— 特别是AnyObject??.None
.
(后两种情况的区别基本上不重要,您不必担心,但如果您有兴趣可以使用dump
查看)。
当然,我们可以再次应用相同的原理:
let step3 = step2??["sourceUrl"] // step3 is AnyObject?? again
现在,将它们全部绑定到一个 if
:
if let url = dictTemp[0]?["source"]??["sourceUrl"] as? String {
// do something with url...
}
警告
这种类型的语法可能很危险,因为它同时适用于数组和字典。在这些情况下您会期望什么?
let dict: NSDictionary = [0: ["source": [3: "result"]]]
dict[0]?["source"]??[3] // returns nil (surprise!)
dict[0]?["source"]??[3 as NSNumber] // returns "result"
let dict2: NSDictionary = [0: ["source": [8, 7, 6, 5, 4]]]
dict2[0]?["source"]??[3] // returns 5
dict2[0]?["source"]??[3 as NSNumber] // returns nil (surprise!)