通过可选绑定在 Swift 中进行安全(边界检查)数组查找?

Safe (bounds-checked) array lookup in Swift, through optional bindings?(通过可选绑定在 Swift 中进行安全(边界检查)数组查找?)
本文介绍了通过可选绑定在 Swift 中进行安全(边界检查)数组查找?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在 Swift 中有一个数组,并尝试访问一个超出范围的索引,就会出现一个不足为奇的运行时错误:

If I have an array in Swift, and try to access an index that is out of bounds, there is an unsurprising runtime error:

var str = ["Apple", "Banana", "Coconut"]

str[0] // "Apple"
str[3] // EXC_BAD_INSTRUCTION

但是,我会认为,使用 Swift 带来的所有可选链接和 安全,执行以下操作将是微不足道的:

However, I would have thought with all the optional chaining and safety that Swift brings, it would be trivial to do something like:

let theIndex = 3
if let nonexistent = str[theIndex] { // Bounds check + Lookup
    print(nonexistent)
    ...do other things with nonexistent...
}

代替:

let theIndex = 3
if (theIndex < str.count) {         // Bounds check
    let nonexistent = str[theIndex] // Lookup
    print(nonexistent)   
    ...do other things with nonexistent... 
}

但事实并非如此——我必须使用 ol' if 语句来检查并确保索引小于 str.count.

But this is not the case - I have to use the ol' if statement to check and ensure the index is less than str.count.

我尝试添加自己的 subscript() 实现,但我不确定如何将调用传递给原始实现,或者在不使用下标表示法的情况下访问项目(基于索引):

I tried adding my own subscript() implementation, but I'm not sure how to pass the call to the original implementation, or to access the items (index-based) without using subscript notation:

extension Array {
    subscript(var index: Int) -> AnyObject? {
        if index >= self.count {
            NSLog("Womp!")
            return nil
        }
        return ... // What?
    }
}

推荐答案

Alex 的回答 有很好的建议和解决方案问题,然而,我偶然发现了一个更好的实现这个功能的方法:

Alex's answer has good advice and solution for the question, however, I've happened to stumble on a nicer way of implementing this functionality:

extension Collection {

    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

Swift3.0和3.1

extension Collection where Indices.Iterator.Element == Index {

    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

感谢 Hamish 提出 Swift 3 的解决方案.

Credit to Hamish for coming up with the solution for Swift 3.

extension CollectionType {

    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

<小时>

示例

let array = [1, 2, 3]

for index in -20...20 {
    if let item = array[safe: index] {
        print(item)
    }
}

这篇关于通过可选绑定在 Swift 中进行安全(边界检查)数组查找?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Why local notification is not firing for UNCalendarNotificationTrigger(为什么没有为UNCalendarNotificationTrigger触发本地通知)
iOS VoiceOver functionality changes with Bundle Identifier(IOS画外音功能随捆绑包标识符而变化)
Pushing UIViewController above UITabBar(将UIView控制器推送到UITabBar上方)
Dropbox Files.download does not start when number of files in folder is gt; 1000(当文件夹中的文件数为1000时,Dropbox Files.Download不会启动)
appearance().setBackgroundImage Not Working On Custom Class(外观().setBackoundImage在自定义类上不起作用)
Show/Hide barButtonItem(显示/隐藏barButtonItem)