c# – swift中对内部数组的本地引用

我来自C#world,并习惯于数组作为引用类型.据我所知,在 swift数组中是值类型,但它们尝试作为引用.

我实际上并不知道如何问我需要什么(我认为这是我需要知道答案才能提出问题的情况),但在C#中我会说我需要存储对内部数组的引用锯齿状数组成局部变量.

考虑以下代码:

// a function to change row values in-place
func processRow(inout row : [Int], _ value : Int)
{
    for col in 0..<row.count
    {
        row[col] = value;
    }
}

// a function to change matrix values in-place
func processMatrix(inout matrix : [[Int]])
{
    for rowIdx in 0..<matrix.count
    {
        // (1) Works with array in-place
        processRow(&(matrix[rowIdx]), -1)

        // (2) Creates local copy
        var r = matrix[rowIdx]; // <--- What to write here to not make a copy but still have this local variable?
        processRow(&r, -2);
    }
}

var matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

processMatrix(&matrix)

print(matrix) // outputs [[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]]

Swift沙箱在这里http://swiftlang.ng.bluemix.net/#/repl/8608824e18317e19b32113e1aa08deeb4ec5ab96ed8cdbe1dbfb4e753e87d528

在这里,我希望我就地处理多维数组,这样我就不会创建数组或数组部分的副本.

在选项(1)中,我将所有内容更改为“-1”,并且它可以工作,但是为此使用了附加功能.

在选项(2)中,我尝试使用局部变量来存储矩阵[rowIdx],但它实际上创建了一个内部数组的副本 – 而不是我想要的;使用此变量会更改数组的副本,而不是原始数据的副本.

如何在选项(1)中实现结果,但使用局部变量而不是函数?也就是说,如何获取对内部数组的引用并将其放入局部变量?

我会理解答案“没有办法解决这个问题”,但我希望这些答案能够附带一些Apple的参考资料.

最佳答案 我不相信有一种方法可以将数组复制到局部变量而无需复制.这就是值类型在Swift中的工作方式. Says Apple:

The most basic distinguishing feature of a value type is that copying — the effect of assignment, initialization, and argument passing — creates an independent instance with its own unique copy of its data[.]

And here:

A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function…

[…]

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

它只是值类型定义的一部分 – 每个数组都是一个值类型.

获得所需结果的最简单方法是将r的值重新分配给要在矩阵中更改的行:

// (2) Creates local copy
var r = matrix[rowIdx]   
processRow(&r, -2)
matrix[rowIdx] = r

与你所建议的最接近的是使用指针:UnsafeMutablePointer,UnsafePointer等.但这确实是与Swift设计使用的方式作斗争.但是,如果你想,它看起来像这样:

func processRow(ptr: UnsafeMutablePointer<Int>, _ value : Int, count: Int) {
    for col in 0..<count {
        ptr.advancedBy(col).memory = value
    }
}

func processMatrix(inout matrix : [[Int]]) {
    for rowIdx in 0..<matrix.count {

        let r = UnsafeMutablePointer<Int>(matrix[rowIdx])
        processRow(r, -2, count: matrix[rowIdx].count)
    }
}

var matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

processMatrix(&matrix)
print(matrix)   // [[2, 2, 2], [2, 2, 2], [2, 2, 2]]
点赞