arrays - 安全访问 Swift 数组的索引 : Ext return not an optional?

标签 arrays swift option-type indices

在文档中,有一个扩展示例,用于添加对 Swift 数组的任何索引(真实的或想象的)的安全和不知情的访问 (编辑 - SO Docs 现已失效,因此该示例被插入底部这个问题)

如果索引不存在,Swift 数组通常会崩溃。看起来这个扩展是专门为解决这个问题而设计的,如果在请求的索引处没有任何内容,则返回 nil

扩展看起来像这样:

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}

扩展的使用如下所示:

if let thirdValue = array[safe: 2] {
    print(thirdValue)
}

在 playgrounds 中尝试这一点表明没有返回不安全索引。我可以告诉。不是可选的,不是零,什么都不是。而且没有崩溃。

当它是安全或不安全的索引值时,这怎么不是从中返回的可选值?我很佩服它的工作原理,只是不太了解它是如何工作的,或者它在做什么。

更新

作为Martin R有帮助地指出,我的大部分问题是不理解/记住/不知道 if let 正在对扩展函数返回一个绝对是 的值产生的可选项进行强制解包可选。如果这种强制解包未能泄露值(即索引处没有值返回包含 nil 的可选值),这将阻止 {trailing closure} 被调用。

然而,它提出了另一个子问题。

如果使用变量来捕获返回值,像这样:

let val = array[safe: 2]
print("val:",  val)

不管结果如何,它都是可选的,但 Swift 提供了一个“有用的”错误提示:

Expression implicitly coerced from 'Int?' to Any

如果这是一个新问题,我深表歉意:为什么这会被强制为 Any?为什么不能(为什么不能)简单地保留为 Int 类型的 Optional?


The following content is from "Accessing indices safely" from Stack Overflow Documentation (archived here); copyright 2017 by Moriya; licensed under CC BY-SA 3.0. An archive of the full Stack Overflow Documentation content can be found at archive.org, in which this example is indexed by its topic ID: 284, as example: 16567.

通过向数组添加以下扩展,可以在不知道索引是否在边界内的情况下访问索引。

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}

例子:

if let thirdValue = array[safe: 2] {
    print(thirdValue)
}

最佳答案

if let val = someOptional { ... }

是一个可选绑定(bind)。如果someOptional != nil 那么条件 为 true,unwrappedsomeOptional! 被分配给 val。 如果 someOptional == nil 则条件为假。

所以在你的情况下

if let thirdValue = array[safe: 2] {
    print(thirdValue)
}

如果 array[safe: 2] != nil,则条件为真(并且执行 if block )。在这种情况下,展开的值将分配给 thirdValue。 另一方面,如果 array[safe: 2] 返回 nil 那么条件 为假且 if block 不被执行。

你可以不使用if条件来打印返回值来验证 它是nil:

let array = [1, 2]
let val = array[safe: 2]
print("val:",  val) // "val: nil"

使用 Swift 3.0.1(Xcode 8.1,使用 GM 种子测试)这将导致编译器警告

main.swift:12:16: warning: expression implicitly coerced from 'Int?' to Any
print("val:",  val)
               ^~~
main.swift:12:16: note: provide a default value to avoid this warning
print("val:",  val)
               ^~~
                   ?? 
main.swift:12:16: note: force-unwrap the value to avoid this warning
print("val:",  val)
               ^~~
                  !
main.swift:12:16: note: explicitly cast to Any with 'as Any' to silence this warning
print("val:",  val)
               ^~~
                   as Any

as a consequence of the implementation of SE-0140 Warn when Optional converts to Any, and bridge Optional As Its Payload Or NSNull.

The warning can be suppressed with

print("val:",  val as Any) // "val: nil"

关于arrays - 安全访问 Swift 数组的索引 : Ext return not an optional?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40254820/

相关文章:

java-8 - Lombok @Builder.Default 强制默认可选值为 null

java - ifPresent 返回一些东西 orElse

java - 调用具有一个可选参数的方法

javascript - 从可能的名称列表中随机选择 JavaScript 文件名称的简单方法

ios - 播放器快速崩溃应用程序

javascript - 如何使用 async.js 映射数组?

ios - Google Places iOS : How to provide context to API for relevant local results

ios - UIButton 阴影不绘制

arrays - 如何在 Rust 1.0 中的堆上分配数组?

javascript - 如果长度小于某个数字,如何从 React 中的数组中过滤项目?