【发布时间】:2019-03-31 22:34:31
【问题描述】:
我正在编写一个名为 TriangularArray<T> 的自定义集合。它表示这样的结构:
x
x x
x x x
x x x x
x x x x x
其中每个x 都是数组中的一个元素。我可以使用从零开始的行号和索引号访问元素。例如,访问以下的 (4, 2):
a
b c
d e f
g h i j
k l m n o
将产生 m(第 5 行,该行中的第三个值)。
我使用[[T]] 作为后备数组,我写了一个像这样的下标:
subscript(_ row: Int, _ index: Int) -> T? {
get {
// innerArray is the [[T]] used for backing
if row < 0 || row >= innerArray.count {
return nil
}
if index < 0 || index > row {
return nil
}
return innerArray[row][index]
}
set {
if row < 0 || row >= innerArray.count {
return
}
if index < 0 || index > row {
return
}
innerArray[row][index] = newValue!
}
}
逻辑是,如果您访问不存在的行和索引,例如 (1, 3),则下标将返回 nil。但是,通过使下标返回T?,setter 中的newValue 也变为可选的,我必须强制解包。
我真的很想对这种事情进行编译时检查:
triangularArray[0, 0] = nil // this should be a compile time error
我尝试在 Google 上查找此内容,但我只找到了这个 question,它已经非常过时了。当然,我们可以在 Swift 4.2 中做得更好,对吧?
【问题讨论】:
-
我认为情况没有改变。下标 getter/setter 仍然返回/采用相同的类型。
-
@MartinR 我明白了。也许我可以利用其他一些语言特性来实现类似的审美,同时禁止
nil... -
我唯一想到的是定义两个下标方法:一个获取/设置一个非可选值,另一个只获取下标返回一个可选值(如“安全数组访问器”目前在forums.swift.org/t/add-accessor-with-bounds-check-to-array/…讨论)
-
事实上,stdlib 处理这个问题的方式是让这些可选返回的访问器只获取,例如
(Bidirectional)Collection的first和last属性。 -
另一个选项(也来自那个 Swift 论坛讨论)是定义一个访问器方法
elementAt(row:index:) -> T?- 另一个问题是你是否真的希望 setter 默默地忽略无效索引,或者如果它应该崩溃。