假设我在 C++ 中执行以下操作:
int i = 1;
int* ptr = &i;
*ptr = 2;
cout << i << '\n';
我想在 swift 中做类似的事情。我可以执行以下操作吗?
var i : Int = 1
var iptr : UnsafeMutablePointer<Int> = &i
iptr.memory = 2
print(i)
并获得相同的结果?
最佳答案
是的。
你不能完全按照你在问题中尝试的那样去做。它不会编译。 Swift 不会让你像这样直接访问一个值的地址。归根结底,原因主要是没有充分的理由这样做。
不过,我们确实在 Swift 中看到了 &
运算符。
首先声明函数参数时有inout
关键字:
func doubleIfPositive(inout value: Float) -> Bool {
if value > 0 {
value *= 2
return true
}
return false
}
要调用此方法,我们需要 &
运算符:
let weMadeARadian = doubleIfPositive(&pi)
当我们有一个函数接受 UnsafeMutablePointer
类型(以及这些指针结构的其他变体)的参数时,我们可以看到它的类似用法。在这种特定情况下,它主要用于与 C 和 Objective-C 的互操作性,我们可以在其中声明一个方法:
bool doubleIfPositive(float * value) -> bool {
if (value > 0) {
value *= 2;
return true;
}
return false;
}
该方法的 Swift 接口(interface)最终看起来像这样:
func doubleIfPositive(value: UnsafeMutablePointer<Float>) -> Bool
从 Swift 调用这个方法实际上看起来就像以前使用 inout
方法一样:
let weMadeARadian = doubleIfPositive(&pi)
但这是我在 Swift 中能找到的 &
运算符仅有的两种用法。
话虽如此,我们可以编写一个函数,利用第二种形式将参数传递给带有&
运算符的方法,并返回包含在一个不安全的可变指针。它看起来像这样:
func addressOf<T>(value: UnsafeMutablePointer<T>) -> UnsafeMutablePointer<T> {
return value
}
它的行为与您对原始代码片段的预期一致:
var i: Int = 1
var iPtr = addressOf(&i)
iPtr.memory = 2
print(i) // prints 2
如 Kevin 所述在 the comments ,如果需要,我们也可以直接分配内存。
var iPtr = UnsafeMutablePointer<Int>.alloc(1)
此处的参数 1
实际上是要分配的空间量。这表示我们要为单个 Int
分配足够的内存。
这大致等同于以下 C 代码:
int * iPtr = malloc(1 * sizeof(int));
但是...
如果你做这些不是为了与 C 或 Objective-C 的互操作性,那么你很可能没有正确地使用 Swifting。因此,在您开始在 Swift 中使用指向值类型的指针四处奔走之前,请确保这是您绝对需要做的事情。自发布 Swift 以来,我一直在编写 Swift,我从未发现需要任何这些恶作剧。
关于swift - Swift 中的简单指针操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36272853/