[英]A mutable pointer to a row in a two-dimensional array
假设有一个二维数组
var myArray: [[MyClass]]
由于数组是Swift中的值类型,因此赋值就像
let line = myArray[lineNumber]
将创建一个副本,而不是引用实际的行。
为了修改数组上的行(例如在行中插入/删除元素)而不复制元素并避免大量使用索引(即在代码中多次使用myArray[lineNumber]
),我尝试了使用C风格的指针方法。
分配
let rowPointer = UnsafePointer(myArray[rowNumber])
似乎没有按预期方式工作,是指myArray[rowNumber][0]
而不是整行。
然而,
let rowPointer = UnsafePointer(myArray) + rowNumber
可以rowPointer.pointee
进行编译并成功完成操作,因此rowPointer.pointee
可以访问整行
由于我还需要通过插入/追加元素来修改行,因此我尝试了可变指针:
let rowPointer = UnsafeMutablePointer(myArray) + rowNumber
但是,此分配会产生编译错误:
无法initializer for type 'UnsafeMutablePointer<_>' with an argument list of type '([[MyClass]])'
调用initializer for type 'UnsafeMutablePointer<_>' with an argument list of type '([[MyClass]])'
有没有一种方法可以通过可变指针访问行?
您真正想做到的是添加对L值的支持。 可以分配或就地编辑的值。 在Swift中,这是通过下标运算符实现的:
struct Matrix<T> {
var rows: [[T]]
init(rows: [[T]]) { self.rows = rows }
init(width: Int, height: Int, initialElement: T) {
let rows = (0..<height).map { _ in
return Array(repeating: initialElement, count: width)
}
self.init(rows: rows)
}
subscript(row: Int, col: Int) -> T {
get { return self.rows[row][col] }
set { self.rows[row][col] = newValue }
}
}
extension Matrix: ExpressibleByArrayLiteral {
init(arrayLiteral: [T]...) {
self.init(rows: arrayLiteral)
}
}
extension Matrix: CustomDebugStringConvertible {
var debugDescription: String {
let height = rows.first?.count ?? 0
let rowText = rows.map { row in
row.map { element in String(describing: element) }.joined(separator: ", ")
}.joined(separator: "],\n\t[")
return """
Matrix(width: \(rows.count), height: \(height), rows:
[\(rowText)]
)
"""
}
}
var matrix: Matrix = [
["A", "B"],
["C", "D"],
]
print(matrix)
matrix[0, 1] = "X"
print(matrix)
我强烈建议您使用不安全的指针方法,因为它可能导致您遇到各种悬空的指针或缓冲区溢出问题。 毕竟,“ Unsafe”名称就在那里!
这是另一个显示可变[[Any]]矩阵的简单版本。
let row1: NSMutableArray = [1,"22",3]
let row2: NSMutableArray = [2,"33",3]
let row3: NSMutableArray = [4,"4",5]
let matrix: [NSMutableArray] = [row1, row2, row3] // Here matrix is an immutable. This is the difference from other answers.
matrix[0][1] = 22
matrix[0][2] = "23"
matrix[0][3] = "2333"
print(type(of:matrix[0][1])) // __NSCFNumber
print(type(of:matrix[0][2])) // NSTaggedPointerString
这更重要。
let line1 = matrix[0] // here `let` again
line1[2] = 33444
print(matrix) //matrix has changed. That means it is using reference.
希望它有用。
这是修改数组实际指针的方法,但是我不确定它在现有数组副本上是否有任何实际价值。 由于值类型始终被复制,因此我们获得了指针,更改了值并为指针分配了新值。
但是,最好将数组视为值类型,以通常的方式进行。 同样,如果您的类是引用类型,则可以简化很多事情。
var myArray: [[Int]] = [[1, 2, 3], [4, 5, 6]]
withUnsafeMutablePointer(to: &myArray) { pointer in
print(pointer)
var pointee = pointer.pointee
pointee[1][1] = 10
pointer.pointee = pointee
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.