Collection和String中index(after :)的不同行为

pac*_*ion 6 swift

我很好奇,为什么这段代码可以正常工作而没有任何错误:

let a = [1]
print(a.index(after: a.endIndex)) // 2
Run Code Online (Sandbox Code Playgroud)

但是,如果我们尝试使用String类型重复此代码,则会收到错误消息:

let s = "a"
print(s.index(after: s.endIndex)) // Fatal error: Can't advance past endIndex
Run Code Online (Sandbox Code Playgroud)

根据CollectionStringdocs,它们都有相同的陈述:

集合的有效索引。i必须小于endIndex

是一个错误还是一切正常?我正在使用Swift 4.2。

pac*_*ion 2

如果我们去查看源码Array我们可以发现:

public func index(after i: Int) -> Int {
    // NOTE: this is a manual specialization of index movement for a Strideable
    // index that is required for Array performance.  The optimizer is not
    // capable of creating partial specializations yet.
    // NOTE: Range checks are not performed here, because it is done later by
    // the subscript function.
    return i + 1
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们可以像这样重写代码,最终导致崩溃:

let a = [1]
let index = a.index(after: a.endIndex)
print(a[index])
Run Code Online (Sandbox Code Playgroud)

因此,对于类型来说,一切都“按预期”工作Array,但是如果我们不想在运行时崩溃,我们必须自己检查结果index

PS @MartinR 的有用链接 https ://forums.swift.org/t/behaviour-of-collection-index-limitedby/19083/3