如何在Swift中创建指针?

4

我是一名使用Swift 3的开发者。

我希望将下面这段C语法转换为Swift:

int myVar;
int *pointer = &myVar;

因此,修改pointermyVar是完全相同的事情。另外,我不知道是否有任何区别,但在我的情况下,myVar是一个包含类元素的数组,而pointer是指向该数组中一个元素的指针。


你试过了吗?var selectedRow = rows[0] 这种方式有什么不符合你的要求的地方吗?(从你的描述来看,我觉得你根本不需要复制,只需要一个共享指针。) - Phillip Mills
它创建了rows[0]的一个副本,但这两个变量是不同的,当我修改selectedRow时,它并不会对rows[0]产生任何影响。是的,我想要一个共享指针。 - Drakalex
4个回答

4
< p >&在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)

2
假设我理解你的要求... 在playground中尝试以下代码。它应该会打印三次“99”。
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 = 5var otherVar = myVarotherVar = 5 不会改变 myVar 的值? - Drakalex
1
不同之处在于对象是通过指针引用的。因此,在我的情况下,我有一个实际的对象和三个包含指向它的一个值的变量。在你的myVar示例中,你正在改变实际的变量内容;它们没有独立的对象引用。 (这就像我输入let selectedRow = Row()并期望其更改反映在testRow中一样。人们有时会尝试这样做,但从来不起作用。 :) ) - Phillip Mills
我非常确定应该是.allocate(capacity: 1)。参数文档:要分配的内存量,以Pointee实例计算。 - nyg
谢谢@nyg。这绝对不是我真正使用过的东西。 - Phillip Mills

1

和@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

0

问题要求的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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接