如何在 Swift 中检查我的数组索引是不是超出范围

Posted

技术标签:

【中文标题】如何在 Swift 中检查我的数组索引是不是超出范围【英文标题】:How Can I Check My Array Index is Out of Range in Swift如何在 Swift 中检查我的数组索引是否超出范围 【发布时间】:2020-10-02 16:59:11 【问题描述】:

例如我做这个请求:

mannschaft18teamid = results2.data.table[17].team_id 

假设第 17 个数组元素不存在。如果它不存在,我该如何设置它的标准值? 我希望该值作为字符串“不存在”。

可能是这样的?:

mannschaft18teamid = results2.data.table[17].team_id ?? "not existing"

它不起作用。模拟器崩溃:Thread 1: Fatal error: Index out of range

它甚至不需要设置一个值。忽略那一行也没关系。

【问题讨论】:

***.com/questions/25976909/… 【参考方案1】:

如果results2.data.table 是一个数组,试试这个:

let index = 17
if results2.data.table.indices.contains(index) 
    mannschaft18teamid = results2.data.table[index].team_id
 else 
    mannschaft18teamid = "not existing"

您收到Index out of range 错误,因此您应该使用indices.contains(index) 检查索引是否存在。更多信息here。

【讨论】:

【参考方案2】:

如果你想要这种语法,你可以扩展 RandomAccessCollection 并实现一个从数组返回可选值的订阅:

extension RandomAccessCollection 
    subscript(index: Index) -> Element? 
        self.indices.contains(index) ? (self[index] as Element) : nil
    

这样你可以做这样的事情:

let arr = ["a", "b", "c"]
print(arr[99] ?? "not existing") // "not existing"

您必须小心确保 Optional 类型是从上下文中推断出来的,例如 ?? 或可选链接 arr[99]?.prop,因为以下内容仍会正常运行,即会失败Index out of range:

let v = arr[99] // error

或者,您可以定义一个带有默认值的下标(就像Dictionary 所做的那样):

extension RandomAccessCollection 
    subscript(index: Index, default defaultValue: @autoclosure () -> Element) -> Element 
        self.indices.contains(index) ? self[index] : defaultValue()
    

let arr = [1,2,3]
print(arr[9, default: 99]) // 99

【讨论】:

【参考方案3】:

如果您不需要它来设置任何值,您可能应该使用保护语句来获取索引处的元素。

guard results2.data.table.count >= 18 else 
    // Bad path, early exit scope
    return 


// Happy path, keep going
mannschaft18teamid = results2.data.table[17].team_id

但是你应该记住,守卫是为了在意外情况下提前退出范围,所以之后的任何事情都不会被执行。如果你想继续执行,那么你应该使用 if let:

if let results2.data.table.count >= 18 
    // Index exists, do stuff
   mannschaft18teamid = results2.data.table[17].team_id

如果您想继续使用 nil 合并运算符 (??) 来提供默认值,那么您应该实现对 Collections 的扩展以安全地访问项目。您可以阅读其他答案或参考this答案。

【讨论】:

Index out of range 错误发生在数组不包含该索引时——不管它是否为 nil。 @aheze 你是绝对正确的,我的错。我更正了。【参考方案4】:

如果索引处的元素不存在,最好使用返回nil 的可选扩展。

扩展

extension Collection where Indices.Iterator.Element == Index 
    subscript (optional index: Index) -> Iterator.Element? 
        return indices.contains(index) ? self[index] : nil
    

用法:

mannschaft18teamid = results2.data.table[optional: 17]?.team_id ?? "not existing"

【讨论】:

我尝试将它与两个 swift 文件一起使用。在一个中,这在另一个中有效,我得到 Invalid redeclaration of 'subscript(optional:)' 我需要更改什么? 声明一次,到处使用。

以上是关于如何在 Swift 中检查我的数组索引是不是超出范围的主要内容,如果未能解决你的问题,请参考以下文章

Swift 致命错误:数组索引超出范围

致命错误:在Swift中访问10个元素的数组时,数组索引超出范围

致命错误:注册后索引超出范围(Firebase、Swift)

Swift 致命错误:数组索引超出范围

如何通过在 swift playground 中传递 Int 数组来创建求和函数并调用它?

SWIFT:为 tableView 计算 numberOfRowsInSection 时,数组索引超出范围