以下代码给我一个错误。有没有办法简单地让这个回报为零?
var testArray: [Int]?
testArray = [1,2,3]
testArray?[9]
答案 0 :(得分:7)
这里有3种可能的东西你可能会混淆:
[Int]?
[Int?]
subscript(index) -> Int?
。你的例子中你得到的是第一种情况 - 可选的数组。也就是说,testArray
为nil
,或者它是包含零个或多个元素的有效数组。
要访问可选内容中的任何内容,您必须首先打开它。你可以用!
强行解开它(除非你有真的正当理由,否则不要这样做 - 不是没有那个原因。不是也没有那个)。或者您可以使用if let
或使用?
,?.
,??
等运算符之一来有条件地展开它。在这种情况下,testArray?[9]
表示,"如果testArray是nil
,则nil
,否则{Some whatever is at position 9}
。但是在第9位没有任何价值 - 这只是一个3元素阵列。所以你得到一个运行时断言。
(编写testArray?[9]
的另一种方式是testArray.map { $0[9] }
,在块中,数组被解包并且有效,但是如果它是nil
,则块永远不会被执行。但结果是仍然你试图访问数组的第9个元素,并且不允许这样做,你得到一个运行时错误)
第二种情况是可选整数数组,这意味着您可以访问testArray[1]
并且返回{Some 2}
,因为数组包含选项。但同样,你无法访问第9个元素,因为没有第9个元素。
最后,第三种情况是调用下标给你一个可选值,如果它不是一个有效的索引,你会得到一个nil
。这似乎是你所期待的。 Swift数组不这样做。如果你按键查找,那么Swift词典就可以了。如果密钥有值,则返回{Some value}
,否则返回nil
。对此的简写理由是字典包含稀疏数据,而数组包含密集数据。
如果您有兴趣,我写了关于pro和anti参数的帖子,以使数组从下标返回选项。但就目前而言,正如其他答案所说,你必须在访问元素之前检查你的界限。您可能想尝试一些辅助方法,如first
,last
,find
,以及map
和filter
等,而不是直接访问元素,因为这会使许多这些问题消失。
(另一个值得思考的有趣的事情 - 上面的所有3个案例都可以组合在一起。所以你可以有一个可选的可选词典,当你访问它时返回选项。如果你仍然对这一切仍然朦胧,尝试在操场上玩耍:)
答案 1 :(得分:2)
您需要明确地进行范围检查,如下所示:
var testArray: [Int]?
testArray = [1,2,3]
let index1 = 9
let numberNine : Int? = index1 < testArray!.count ? testArray![ index1 ] : nil
println(numberNine)
let index2 = 2
let numberTwo : Int? = index2 < testArray!.count ? testArray![ index2 ] : nil
println(numberTwo!)
条件表达式... ?
... :
...会在决定评估:
的哪一侧之前检查条件,因此testArray![ index1 ]
受到保护条件:当索引超出范围时,它不会导致异常。
答案 2 :(得分:1)
如果您想知道数组是否包含特定值,您可以使用全局contains
函数:
var testArray: [Int]?
testArray = [1,2,3]
if let actualTestArray = testArray {
let doesContain9 = contains(actualTestArray, 9)
println(doesContain9) // prints "false"
}
如果您可以testArray
非可选,则可以执行
var testArray: [Int]
testArray = [1,2,3]
let doesContain9 = contains(testArray, 9)
println(doesContain9) // prints "false"
答案 3 :(得分:0)
在Swift中尝试访问索引时,应该在运行时抛出类似EXC_BAD_INSTRUCTION
的错误。
也许你想使用NSDictionary
。实际上,使用字典时,在尝试访问不存在的密钥时,您不会遇到任何运行时错误。它只会返回nil
如果要使用数组,在使用数组的count
属性进行访问之前,需要检查数组中的项目数