我正在学习Python,并希望确认Objective-C和Swift中的某种行为.
测试如下:
蟒蛇
def replace(list): list[0] = 3 print(list) aList = [1, 2, 3] print(aList) replace(aList) print(aList)
Objective-C的
- (void)replace:(NSMutableArray *)array { array[0] = @1; NSLog(@"array: %@, address: %p\n%lx", array, array, (long)&array); } NSMutableArray *array = [@[@1, @2, @3] mutableCopy]; NSLog(@"original: %@, address: %p \n%lx", array, array, (long)&array); [self replace:array]; NSLog(@"modified: %@, address: %p \n%lx", array, array, (long)&array);
迅速
var numbers = [1, 2, 3] let replace = { (var array:[Int]) -> Void in array[0] = 2 print("array: \(array) address:\(unsafeAddressOf(array as! AnyObject))") } print("original: \(numbers) address:\(unsafeAddressOf(numbers as! AnyObject))") replace(numbers) print("modified: \(numbers) address:\(unsafeAddressOf(numbers as! AnyObject))")
除了Swift中的地址部分之外,所有结果都按预期发布.在Objective-C中,数组的地址在original
和中保持不变modified
,但Swift的打印结果是:
original: [1, 2, 3] address:0x00007f8ce1e092c0 array: [2, 2, 3] address:0x00007f8ce1f0c5d0 modified: [1, 2, 3] address:0x00007f8ce4800a10
有什么我想念的吗?
Swift中的数组具有值语义,而不是Python和Objective-C中数组的引用语义.您看到不同地址(以及地址)的原因是,每次进行as! AnyObject
强制转换时,您实际上都在告诉Swift将您的Array
结构桥接到一个实例NSArray
.由于您桥接了三次,因此您将获得三个不同的地址.
您不应该考虑Swift数组的地址,但如果您想(暂时)获取数组缓冲区的地址,您可以这样做:
func getBufferAddress(array: [T]) -> String { return array.withUnsafeBufferPointer { buffer in return String(buffer.baseAddress) } }
这使您可以看到缓冲区的写时复制:
var numbers = [1, 2, 3] let numbersCopy = numbers // the two arrays share a buffer here getBufferAddress(numbers) // "0x00007fba6ad16770" getBufferAddress(numbersCopy) // "0x00007fba6ad16770" // mutating `numbers` causes a copy of its contents to a new buffer numbers[0] = 4 // now `numbers` has a new buffer address, while `numbersCopy` is unaffected getBufferAddress(numbers) // "0x00007ff23a52cc30" getBufferAddress(numbersCopy) // "0x00007fba6ad16770"