关于swift误导性文件我错了吗?

关于swift误导性文件我错了吗?,swift,Swift,对于数组方法: @inlinable public func index(_ i: Int, offsetBy distance: Int, limitedBy limit: Int) -> Int? 文件给出了一个例子: /// let numbers = [10, 20, 30, 40, 50] /// if let i = numbers.index(numbers.startIndex, /// offse

对于数组方法:

@inlinable public func index(_ i: Int, offsetBy distance: Int, limitedBy limit: Int) -> Int?
文件给出了一个例子:

///     let numbers = [10, 20, 30, 40, 50]
///     if let i = numbers.index(numbers.startIndex,
///                              offsetBy: 4,
///                              limitedBy: numbers.endIndex) {
///         print(numbers[i])
///     }
为什么它使用
数字。endIndex
对于
限制
参数,这显然是错误的,我们应该使用
数字。endIndex-1
,它在这里工作,因为
距离
参数是4,如果
距离
是5,它将崩溃


我认为这是一个糟糕的例子,或者我遗漏了什么?

你是对的,该代码不能防止“索引超出范围”错误
endIndex
是数组(或通常是集合的)“结束”位置:它是有效的索引,但下标无效

对于非负偏移

if let i = numbers.index(numbers.startIndex,
                         offsetBy: offset,
                         limitedBy: numbers.endIndex), i != numbers.endIndex {
    print(numbers[i])
}
这是一种安全的变体。对于数组,也可以使用
数字.endIndex-1
作为限制。但这不适用于任意集合,因为并非所有集合都由整数索引(
String
就是一个很好的例子)

您还可以检查偏移量是否为
offset
,但请注意,访问任意集合的
count
可能是一个O(N)操作

另一个变体是

if let num = numbers.dropFirst(offset).first {
    print(num)
}
它适用于任意集合。与前面的示例一样,必须单独排除可能的负偏移

你也可以使用

if numbers.indices.contains(index) {
    print(numbers[index])
}

为了安全起见,请订阅。如果您记住集合索引不一定是零基的,也不一定是整数,则这适用于任意集合。

您是对的,如果距离为5,则会崩溃,这使得示例具有误导性。您应该为文档提交一份错误报告。我同意这是一个糟糕的例子–还有另一个关于
集合的例子
的文档快速grep显示在Array.swift、ArraySlice.swift、BidirectionalCollection.swift、Collection.swift、RandomAccessCollection.swift中也有类似(糟糕)的例子,StringCharacterView.swift@MartinR:)@Hamish:你说得对,我错过了。或者对于任何
BidirectionalCollection
limitby
index(before:endIndex)