I am trying to program a two-dimensional data storage struct for various data types. However, I am struggling with the subscript for setting the data due 'Cannot assign value of type 'T' to subscript of type 'T' errors. Any help is much appreciated!
struct dataMatrix<T> : Sequence, IteratorProtocol {
var rows: Int, columns: Int
var data: [T]
var position = 0
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
data = Array<T>()
}
func valueAt(column: Int, row: Int) -> T? {
guard column >= 0 && row >= 0 && column < columns else {
return nil
}
let indexcolumn = column row * columns
guard indexcolumn < data.count else {
return nil
}
return data[indexcolumn]
}
}
subscript<T>(column: Int, row:Int) -> T?{
get{
return valueAt(column: column, row: row) as? T
}
set{
data[(column * row) column] = (newValue as! T) // does not compile
}
}
// sequence iterator protorocl methods
mutating func next() -> String? {
if position <= data.count{
print(position)
defer { position = 1 }
return "\(position)"
}else{
defer {position = 0}
return nil
}
}
}
CodePudding user response:
subscript<T>(column: Int, row:Int) -> T?{
defines a generic method with a type placeholder T
which is unrelated to the generic type T
of struct dataMatrix<T>
. The solution is simple: Remove the type placeholder:
subscript(column: Int, row: Int) -> T? {
// ...
}
That makes also the type casts inside the getter and setter unnecessary. You only have to decide what to do if the setter is called with a nil
argument (e.g.: nothing):
subscript(column: Int, row: Int) -> T? {
get {
return valueAt(column: column, row: row)
}
set {
if let value = newValue {
data[(column * row) column] = value
}
}
}
Another option is to make the return type of the subscript method non-optional, and treat invalid indices as a fatal error (which is how the Swift Array
handles it):
subscript(column: Int, row: Int) -> T {
get {
guard let value = valueAt(column: column, row: row) else {
fatalError("index out of bounds")
}
return value
}
set {
data[(column * row) column] = newValue
}
}