直接分配 UnsafePointer

Bra*_*n M 2 unsafe-pointers swift

有人可以向我解释我在这里缺少什么吗?

给定的

let index: Int32 = 100
Run Code Online (Sandbox Code Playgroud)

为什么这不行:

// Use of extraneous '&'
let ptr = &index // Type inference?
Run Code Online (Sandbox Code Playgroud)

甚至:

// Use of extraneous '&'
let ptr: UnsafePointer<Int32> = &index
Run Code Online (Sandbox Code Playgroud)

但这是:

{
    func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
        return num
    }
    let ptr = point(num: &index)
}
Run Code Online (Sandbox Code Playgroud)

这将是 C 中的简单等价物:

int index = 100;
int *ptr = &index;
Run Code Online (Sandbox Code Playgroud)

我真的必须定义一个函数,从字面上获取引用的值并传回完全相同的引用吗?感觉有些不对劲。似乎我在这里遗漏了一些东西,甚至可能是根本的。

如何将 UnsafePointer 分配给它所在类型的内存地址(在本例中为 Int32)???

谢谢!

编辑:

最终我试图完成的是,我需要将几种不同的结构写入一个二进制文件。变量index将是结构的属性。我现在要走的路径涉及一个文件OutputStream。我不介意收到关于此的建议,但超出了原始问题的范围。

Ham*_*ish 5

我不知道确切的理由,但大概let ptr = &index是不允许的,因为不能保证您可以在ptr不调用未定义行为的情况下取消引用(假设index不是全局或static存储变量 - Swift 保证稳定和唯一的指针值的唯一情况) .

与其他语言不同,Swift 不保证局部变量将保持初始化状态,直到它声明的作用域结束——优化器可以自由地提前取消初始化。let ptr = &index因此,允许会使编写不健全的代码变得太容易。

值得注意的是,您的示例:

func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
    return num
}
let ptr = point(num: &index)
Run Code Online (Sandbox Code Playgroud)

也不健全。尝试取消引用ptrfromlet ptr = point(num: &index)是未定义的行为,因为 inout-to-pointer 参数转换会产生一个仅在函数调用期间有效的临时指针。

如果你想有一个范围的临时指针的值,你可以使用withUnsafePointer(to:)-例如:

func baz() {
  var foo = 5
  withUnsafePointer(to: &foo) { ptr in
    // use `ptr` here – do not escape it!
  }

  // In Swift 4.2 you can also use `withUnsafePointer(to:)` on let constants.
  let bar = 5
  withUnsafePointer(to: bar) { ptr in
    // use `ptr` here – do not escape it!
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,该指针仅在闭包期间有效 - 尝试对其进行转义将导致未定义的行为。