安全访问 Swift 数组的索引:Ext return 不是可选的?
Accessing indices of Swift arrays safely: Ext return not an optional?
在文档中,有一个扩展示例,用于添加对 Swift 数组的任何索引(真实的或想象的)的安全和不知情的访问 (编辑 - SO Docs 现已失效所以这个例子被插入到这个问题的底部).
Swift 如果索引不存在,数组通常会崩溃。似乎这个扩展是明确设计来解决这个问题的 returning nil
如果在请求的索引中没有任何内容。
扩展如下所示:
extension Array {
subscript (safe index: Int) -> Element? {
return indices ~= index ? self[index] : nil
}
}
扩展的使用如下所示:
if let thirdValue = array[safe: 2] {
print(thirdValue)
}
在 playground 中进行尝试表明没有返回不安全索引。我可以告诉。不是可选的,不是零,什么都不是。而且没有崩溃。
当它是安全或不安全的索引值时,这怎么不是从中返回的可选值?我很佩服它的工作原理,只是不太了解它是如何工作的,或者它在做什么。
更新
正如 Martin R 指出的那样,我的大部分问题不是 understanding/remembering/knowing if let
正在对扩展函数 [=61= 产生的可选项进行强制解包]ing 一个绝对是 可选 的值。如果这种强制解包未能泄露值(即索引 return 处没有值是一个包含 nil
的可选值),这将阻止 {trailing closure}
被调用。
然而它提出了另一个子问题。
如果使用变量来捕获 return 值,像这样:
let val = array[safe: 2]
print("val:", val)
无论结果如何,它都是可选的,但 Swift 提供了一个 "helpful" 错误提示:
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 { ... }
是一个 可选绑定。 如果 someOptional != nil
则条件
为真,unwrapped 值 someOptional!
被分配给 val
。
如果 someOptional == nil
则条件为假。
所以在你的情况下
if let thirdValue = array[safe: 2] {
print(thirdValue)
}
如果 array[safe: 2] != nil
,则条件为真(并且执行 if 块)。在这种情况下,展开后的值将分配给 thirdValue
。
另一方面,如果 array[safe: 2]
returns nil
那么条件
为假且 if 块未执行。
您可以打印 return 值而不使用 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
由于实施
SE-0140 Warn when Optional converts to Any, and bridge Optional As Its Payload Or NSNull.
警告可以用
抑制
print("val:", val as Any) // "val: nil"
在文档中,有一个扩展示例,用于添加对 Swift 数组的任何索引(真实的或想象的)的安全和不知情的访问 (编辑 - SO Docs 现已失效所以这个例子被插入到这个问题的底部).
Swift 如果索引不存在,数组通常会崩溃。似乎这个扩展是明确设计来解决这个问题的 returning nil
如果在请求的索引中没有任何内容。
扩展如下所示:
extension Array {
subscript (safe index: Int) -> Element? {
return indices ~= index ? self[index] : nil
}
}
扩展的使用如下所示:
if let thirdValue = array[safe: 2] {
print(thirdValue)
}
在 playground 中进行尝试表明没有返回不安全索引。我可以告诉。不是可选的,不是零,什么都不是。而且没有崩溃。
当它是安全或不安全的索引值时,这怎么不是从中返回的可选值?我很佩服它的工作原理,只是不太了解它是如何工作的,或者它在做什么。
更新
正如 Martin R 指出的那样,我的大部分问题不是 understanding/remembering/knowing if let
正在对扩展函数 [=61= 产生的可选项进行强制解包]ing 一个绝对是 可选 的值。如果这种强制解包未能泄露值(即索引 return 处没有值是一个包含 nil
的可选值),这将阻止 {trailing closure}
被调用。
然而它提出了另一个子问题。
如果使用变量来捕获 return 值,像这样:
let val = array[safe: 2]
print("val:", val)
无论结果如何,它都是可选的,但 Swift 提供了一个 "helpful" 错误提示:
Expression implicitly coerced from 'Int?' to Any
如果这是一个新问题,我深表歉意:为什么要将其强制 Any
?为什么不能(为什么不能)简单地保留为 Int?
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 { ... }
是一个 可选绑定。 如果 someOptional != nil
则条件
为真,unwrapped 值 someOptional!
被分配给 val
。
如果 someOptional == nil
则条件为假。
所以在你的情况下
if let thirdValue = array[safe: 2] {
print(thirdValue)
}
如果 array[safe: 2] != nil
,则条件为真(并且执行 if 块)。在这种情况下,展开后的值将分配给 thirdValue
。
另一方面,如果 array[safe: 2]
returns nil
那么条件
为假且 if 块未执行。
您可以打印 return 值而不使用 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
由于实施 SE-0140 Warn when Optional converts to Any, and bridge Optional As Its Payload Or NSNull.
警告可以用
抑制print("val:", val as Any) // "val: nil"