Negative ArraySlice:索引超出范围

时间:2016-03-27 19:44:57

标签: swift

我无法弄清楚为什么我在循环中的第二次迭代中得到错误。你能帮我理解问题的来源吗?

let NumTracks = 3
let TrackBytes = 2

func readBytes(input: [UInt8]?) {
    if let input = input  {
        var input = input[0..<input.count]
        for _ in 0..<NumTracks {
            print(input[0..<TrackBytes]) // fatal error: Negative ArraySlice index is out of range
            input = input[TrackBytes..<input.count]
        }
    }
}
let samples = [UInt8]?([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
readBytes(samples)

another test case like this one并没有理由为什么会崩溃。

修改

当我使用此代码变体时,我没有收到错误(我仍然不知道原因):

let NumTracks = 3
let TrackBytes = 2

func readBytes(input: [UInt8]?) {
    if let input = input  {
        var input = input[0..<input.count]
        for _ in 0..<NumTracks {
            print(input[input.startIndex..<input.startIndex.advancedBy(2)])
            input = input[input.startIndex.advancedBy(2)..<input.endIndex]
        }
    }
}
let samples = [UInt8]?([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
readBytes(samples)

1 个答案:

答案 0 :(得分:5)

原因是采用数组切片保留原始数据 数组索引:

input = input[TrackBytes..<input.count]

在您的情况下,在第一次致电

之后
input

TrackBytes的第一个有效索引是0而不是input[0..<TrackBytes] 和 因此下次调用

startIndex

导致运行时错误。

所以集合的func readBytes(input: [UInt8]?) { if let input = input { var input = input[0..<input.count] for _ in 0..<NumTracks { print([UInt8](input.prefix(TrackBytes))) input = input.suffixFrom(input.startIndex + TrackBytes) } } } 不一定是零,你已经找到了解决方案,另一个是

func readBytes(input: [UInt8]?) {
    if let input = input {
        for start in 0.stride(to: NumTracks * TrackBytes, by: TrackBytes) {
            print([UInt8](input[start ..< start + TrackBytes])) 
        }
    }
}

或甚至更短,无需重复修改本地数组切片:

{{1}}