我是一名使用Swift 3的开发者。
我希望将下面这段C语法转换为Swift:
int myVar;
int *pointer = &myVar;
因此,修改pointer
或myVar
是完全相同的事情。另外,我不知道是否有任何区别,但在我的情况下,myVar
是一个包含类元素的数组,而pointer
是指向该数组中一个元素的指针。
&
在Swift中也存在,但只能作为参数列表的一部分使用(例如init、func、closure)。
var i = 5
let ptr = UnsafeMutablePointer(&i)
print(ptr.pointee) // 5
// or
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 1)
ptr.initialize(to: 5)
// or with a closure
let ptr: UnsafePointer = { $0 }(&i)
class Row {
var rowNumber = 0
}
var rows = [Row]()
let testRow = Row()
testRow.rowNumber = 1
rows.append(testRow)
let selectedRow = rows[0]
selectedRow.rowNumber = 99
print(testRow.rowNumber)
print(selectedRow.rowNumber)
print(rows[0].rowNumber)
默认情况下,在赋值语句中不会复制对象。如果它是一个结构体,那就不同了。
补充一点:
如果您想对标量值进行类似的操作而不是对象,则Swift提供了各种类型的包装器。
let intPointer = UnsafeMutablePointer<Int>.allocate(capacity: 8) // Should be 1, not 8 according to comment re: docs
let other = intPointer
other.pointee = 34
print(intPointer.pointee)
(警告:除了在游乐场进行实验之外,我还没有使用这些包装器来做其他事情。在进行一些研究之前不要相信它)
var myVar = 5
,var otherVar = myVar
和 otherVar = 5
不会改变 myVar
的值? - DrakalexmyVar
示例中,你正在改变实际的变量内容;它们没有独立的对象引用。 (这就像我输入let selectedRow = Row()
并期望其更改反映在testRow
中一样。人们有时会尝试这样做,但从来不起作用。 :) ) - Phillip Mills.allocate(capacity: 1)
。参数文档:要分配的内存量,以Pointee
实例计算。 - nyg和@Phillip举的例子一样,但我使用了结构体。在这个例子中,rows[0]不会改变:
struct Row {
var rowNumber = 0
}
var rows = [Row]()
var testRow = Row()
testRow.rowNumber = 1
rows.append(testRow)
var selectedRow = rows[0]
selectedRow.rowNumber = 99
print(testRow.rowNumber) // prints 1
print(selectedRow.rowNumber) // prints 99
print(rows[0].rowNumber) // prints 1
问题要求的C风格指针(不安全指针)不存在,但对象通过引用共享,结构体通过值传递:
在Swift中,引用类型
的赋值
、传参
和返回值
都是通过引用传递,而值类型
则是通过复制传递。
结构体
在代码中传递时总是被复制的,但类
则是通过引用传递的。
class Song {
init(title: String, image: String, file: String, volume: Float, queuePlayer: AVQueuePlayer, playerLooper: AVPlayerLooper?) {
self.title = title
self.image = image
...
}
var title: String
var image: String
...
}
var aSong = Song(title: "", image: "", ...)
var arrOfSongReferences: [Song] = [Song]()
arrOfSongReferences.append(aSong)
var ptrToASong: Song = aSong
aSong = nil
// Due to Swift garbage collection ARC (Automatic Reference Counting), we still have references to the original aSong object so it won't be deleted
struct Song {
var title: String
var image: String
...
}
var aSong: Song = Song(title: "", image: "", ...)
var copyOfASong: Song = aSong
您也可以将参数通过引用传递到函数中
// this would be inside a class, perhaps Player. It doesn't have to be a static btw
static func playSound(_ sound: inout Song, volume: Float = 0.0) {
if (sound.playerLooper == nil) {
...
}
}
// usage
Player.playSound(sound: &aSong)
var selectedRow = rows[0]
这种方式有什么不符合你的要求的地方吗?(从你的描述来看,我觉得你根本不需要复制,只需要一个共享指针。) - Phillip Millsrows[0]
的一个副本,但这两个变量是不同的,当我修改selectedRow
时,它并不会对rows[0]
产生任何影响。是的,我想要一个共享指针。 - Drakalex