关于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
limitbyindex(before:endIndex)