3 回答
TA贡献1865条经验 获得超7个赞
我偶然发现了一种更好的实现此功能的方法:
Swift 3.2和更新版本
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
}}Swift 3.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
}}斯威夫特2
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)
}}TA贡献2019条经验 获得超9个赞
如果你真的想要这种行为,它就像你想要一个Dictionary而不是一个数组。字典nil在访问丢失的密钥时返回,这是有道理的,因为要知道密钥是否存在于字典中要困难得多,因为这些密钥可以是任何东西,在数组中密钥必须在以下范围内:0to count。迭代这个范围是非常常见的,你可以绝对肯定在循环的每次迭代中都有一个真正的值。
我认为它不能以这种方式工作的原因是Swift开发人员做出的设计选择。举个例子:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0] )"
如果您已经知道索引存在,就像在大多数使用数组的情况下一样,这段代码很棒。但是,如果访问标可能可能返回nil,那么你已经改变了返回类型的Array的subscript方法是可选的。这会将您的代码更改为:
var fruits: [String] = ["Apple", "Banana", "Coconut"]var str: String = "I ate a \( fruits[0]! )"// ^ Added
这意味着每次迭代数组时都需要解包一个可选项,或者使用已知索引执行任何其他操作,因为很少有人可以访问超出范围的索引。Swift设计者在访问越界索引时以牺牲运行时异常为代价,选择了较少的可选解包。崩溃比nil你在某个地方没想到的逻辑错误更可取。
我同意他们的观点。因此,您将不会更改默认Array实现,因为您将破坏所有需要来自数组的非可选值的代码。
相反,您可以子类化Array,并覆盖subscript以返回可选项。或者,更实际地,您可以Array使用执行此操作的非下标方法进行扩展。
extension Array {
// Safely lookup an index that might be out of bounds, // returning nil if it does not exist func get(index: Int) -> T? {
if 0 <= index && index < count {
return self[index]
} else {
return nil
}
}}var fruits: [String] = ["Apple", "Banana", "Coconut"]if let fruit = fruits.get(1) {
print("I ate a \( fruit )")
// I ate a Banana}if let fruit = fruits.get(3) {
print("I ate a \( fruit )")
// never runs, get returned nil}Swift 3更新
func get(index: Int) ->T? 需要被替换 func get(index: Int) ->Element?
- 3 回答
- 0 关注
- 726 浏览
添加回答
举报
