I am writing a custom collection called TriangularArray<T>. It represents a structure like this:
x
x x
x x x
x x x x
x x x x x
where each x is an element in the array. I can access the elements with a row number and an index number, both zero-based. For example, accessing (4, 2) of the following:
a
b c
d e f
g h i j
k l m n o
will result in m (5th row, third value in that row).
I used a [[T]] as the backing array and I wrote a subscript like this:
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!
}
}
The logic is that the subscript will return nil if you access a non-existent row and index, like (1, 3). However, by making the subscript return T?, the newValue in the setter also becomes optional, and I have to force unwrap it.
I really want compile-time checking of this kind of thing:
triangularArray[0, 0] = nil // this should be a compile time error
I tried looking this up on Google but I only found this question, which is very outdated. Surely we can do better in Swift 4.2, right?