在文档中,有一个扩展示例,用于添加对 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,unwrapped 值 someOptional!
被分配给 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/