Swift可选数组索引错误

时间:2014-12-22 19:46:26

标签: arrays swift optional

以下代码给我一个错误。有没有办法简单地让这个回报为零?

var testArray: [Int]?

testArray = [1,2,3]

testArray?[9]

4 个答案:

答案 0 :(得分:7)

这里有3种可能的东西你可能会混淆:

  1. 数组的可选项 - 即可能包含整数数组的变量:[Int]?
  2. 一个选项数组 - 也就是说,包含可能是整数的变量的数组:[Int?]
  3. 返回可选项的下标,因为该下标可能无效 - 也就是说,如果索引有效,则可能返回整数的下标:subscript(index) -> Int?
  4. 你的例子中你得到的是第一种情况 - 可选的数组。也就是说,testArraynil,或者它是包含零个或多个元素的有效数组。

    要访问可选内容中的任何内容,您必须首先打开它。你可以用!强行解开它(除非你有真的正当理由,否则不要这样做 - 不是没有那个原因。不是也没有那个)。或者您可以使用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。对此的简写理由是字典包含稀疏数据,而数组包含密集数据。

    如果您有兴趣,我写了关于proanti参数的帖子,以使数组从下标返回选项。但就目前而言,正如其他答案所说,你必须在访问元素之前检查你的界限。您可能想尝试一些辅助方法,如firstlastfind,以及mapfilter等,而不是直接访问元素,因为这会使许多这些问题消失。

    (另一个值得思考的有趣的事情 - 上面的所有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属性进行访问之前,需要检查数组中的项目数