Swift 具有通用数据类型的下标
Swift subscript with generic data type
我正在尝试为各种数据类型编写一个二维数据存储结构。但是,由于“无法将 'T' 类型的值分配给 'T' 类型的下标错误,我正在努力设置数据的下标。非常感谢任何帮助!
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
}
}
}
subscript<T>(column: Int, row:Int) -> T?{
定义了一个带有类型占位符 T
的泛型方法,它与 struct dataMatrix<T>
的泛型类型 T
无关。解决方案很简单:删除类型占位符:
subscript(column: Int, row: Int) -> T? {
// ...
}
这也使得 getter 和 setter 中的类型转换变得不必要。如果使用 nil
参数调用 setter(例如:什么都没有),您只需决定要做什么:
subscript(column: Int, row: Int) -> T? {
get {
return valueAt(column: column, row: row)
}
set {
if let value = newValue {
data[(column * row) + column] = value
}
}
}
另一种选择是使下标方法的 return 类型成为非可选的,并将无效索引视为致命错误(这就是 Swift Array
处理它的方式):
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
}
}
我正在尝试为各种数据类型编写一个二维数据存储结构。但是,由于“无法将 'T' 类型的值分配给 'T' 类型的下标错误,我正在努力设置数据的下标。非常感谢任何帮助!
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
}
}
}
subscript<T>(column: Int, row:Int) -> T?{
定义了一个带有类型占位符 T
的泛型方法,它与 struct dataMatrix<T>
的泛型类型 T
无关。解决方案很简单:删除类型占位符:
subscript(column: Int, row: Int) -> T? {
// ...
}
这也使得 getter 和 setter 中的类型转换变得不必要。如果使用 nil
参数调用 setter(例如:什么都没有),您只需决定要做什么:
subscript(column: Int, row: Int) -> T? {
get {
return valueAt(column: column, row: row)
}
set {
if let value = newValue {
data[(column * row) + column] = value
}
}
}
另一种选择是使下标方法的 return 类型成为非可选的,并将无效索引视为致命错误(这就是 Swift Array
处理它的方式):
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
}
}