Answers:
Swift中的一种优雅方式:
let isIndexValid = array.indices.contains(index)
index >= 0 && index < array.count
不是最坏的情况是n比较。
ArraySlice
,则第一个索引将不会为0,因此这样做index >= 0
将不是一个足够好的检查。.indices
而是在任何情况下都有效。
extension Collection {
subscript(optional i: Index) -> Iterator.Element? {
return self.indices.contains(i) ? self[i] : nil
}
}
使用此方法,当在索引中添加关键字optional时,您将获得一个可选值,这意味着即使索引超出范围,程序也不会崩溃。在您的示例中:
let arr = ["foo", "bar"]
let str1 = arr[optional: 1] // --> str1 is now Optional("bar")
if let str2 = arr[optional: 2] {
print(str2) // --> this still wouldn't run
} else {
print("No string found at that index") // --> this would be printed
}
optional
在参数中使用时可读。谢谢!
extension Collection {
subscript(safe index: Index) -> Iterator.Element? {
guard indices.contains(index) else { return nil }
return self[index]
}
}
if let item = ["a", "b", "c", "d"][safe: 3] { print(item) }//Output: "d"
//or with guard:
guard let anotherItem = ["a", "b", "c", "d"][safe: 3] else {return}
print(anotherItem) // "d"
if let
与数组结合进行样式编码时,增强了可读性
您可以用一种更安全的方式重写它来检查数组的大小,并使用三元条件:
if let str2 = (arr.count > 2 ? arr[2] : nil) as String?
if
语句,而不是if
原始代码中的一个语句。我的代码用if
条件运算符替换了第二个,让您保持单个else
而不是强制两个单独的else
块。
if
OP的问题的全部内容都将落入Antonio的答案的“ then”分支内,因此将有两个嵌套的if
s。我正在查看OP代码作为一个小示例,因此我假设他仍然想要一个if
。我同意你的看法,在他的例子if
中没有必要。但是同样,整个语句毫无意义,因为OP知道数组没有足够的长度,并且数组的任何元素都不是nil
,因此他可以删除if
并仅保留其else
块。
对我来说,我更喜欢方法。
// MARK: - Extension Collection
extension Collection {
/// Get at index object
///
/// - Parameter index: Index of object
/// - Returns: Element at index or nil
func get(at index: Index) -> Iterator.Element? {
return self.indices.contains(index) ? self[index] : nil
}
}
感谢@Benno Kress
extension Array {
func isValidIndex(_ index : Int) -> Bool {
return index < self.count
}
}
let array = ["a","b","c","d"]
func testArrayIndex(_ index : Int) {
guard array.isValidIndex(index) else {
print("Handle array index Out of bounds here")
return
}
}
对我来说,处理indexOutOfBounds是工作。
index < array.count
吗?