让我们说我在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)
并取得同样的结果?
答案 0 :(得分:3)
您无法完全按照您在问题中尝试的方式完成此操作。它不会编译。 Swift不会让你直接访问这样的值的地址。在一天结束时,原因主要是因为没有充分的理由这样做。
我们确实在Swift中看到&
运算符。
首先,在声明函数参数时有inout
关键字:
func doubleIfPositive(inout value: Float) -> Bool {
if value > 0 {
value *= 2
return true
}
return false
}
要调用此方法,我们需要&
运算符:
let weMadeARadian = doubleIfPositive(&pi)
当我们有一个带有类型UnsafeMutablePointer
的参数(以及这些指针结构的其他变体)的函数时,我们可以看到它类似地使用。在这种特定情况下,它主要用于与C&amp; C的互操作性。 Objective-C,我们可以在这里声明一个方法:
bool doubleIfPositive(float * value) -> bool {
if (value > 0) {
value *= 2;
return true;
}
return false;
}
该方法的Swift接口最终看起来像这样:
func doubleIfPositive(value: UnsafeMutablePointer<Float>) -> Bool
从Swift调用此方法实际上看起来就像之前使用inout
方法时那样:
let weMadeARadian = doubleIfPositive(&pi)
但是这些是我在Swift中找到的&
运算符的唯一两种用途。
话虽如此,我们可以编写一个函数,该函数利用第二种形式将参数传递给带有&
运算符的方法,并返回包含在不安全的mutable中的变量指针。它看起来像这样:
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,而且我从未发现需要任何这些恶作剧。
答案 1 :(得分:3)
像这样(不是唯一的方式,但很清楚):
var i : Int = 1
withUnsafeMutablePointer(&i) {
iptr -> () in
iptr.memory = 2
}
print(i)
这不是一个非常有趣的例子,但它与你的伪代码完全平行,我们确实已经直接进入已分配的内存并改变它,这就是你想要做的。
当你想要做的事情就像循环通过内存一样快,就像在C中做指针运算一样快。这种事情会变得更有趣。