为什么我不能用 (&myUInt32) 或 (&[myUInt32]) 初始化 Swift UnsafeMutablePointer<UInt32>

Why can’t I initialize a Swift UnsafeMutablePointer<UInt32> with (&myUInt32) or (&[myUInt32])

文档说:"When a function is declared as taking an UnsafeMutablePointer argument, it can accept any of the following... An in-out expression whose operand is a stored lvalue of type Type, which is passed as the address of the lvalue." 我可以复制示例并进行演示。

func takesAMutablePointer<T>(x: UnsafeMutablePointer<T>) -> UnsafeMutablePointer<T>
    {
        return x
    }

func useAMutablePointer()
    {
        var legInt :UInt32 = 42
        var legIntArray: [UInt32] = [legInt]
        var legIntPtr: UnsafeMutablePointer<UInt32>
        legIntPtr = takesAMutablePointer(&legInt)
        legIntPtr = takesAMutablePointer(&legIntArray)
        legIntPtr = UnsafeMutablePointer(&legInt) //Compile error!
        legIntPtr = UnsafeMutablePointer(&legIntArray) //Compile error!
    }

Xcode 表明 UnsafeMutablePointer 具有以下初始化程序:

init<U>(_ from: UnsafeMutablePointer<U>) ,但是当我尝试像我的函数一样使用它时,编译器错误是 Cannot find an initializer for type 'UnsafeMutablePointer<T>' that accepts an argument list of type '(inout UInt32)' 所以,

  1. 获取 UnsafeMutablePointer<UInt32> 到 legInt 的直接方法是什么?
  2. 为什么我不能按预期使用初始化器?

谢谢!

我有点猜测,但原因似乎是 UnsafeMutablePointer<T> 具有 通用 初始化程序

init<U>(_ from: UnsafeMutablePointer<U>)

其中 <U><T> 无关。编译器好像不能 在

中推断类型<U>
legIntPtr = UnsafeMutablePointer(&legInt) //Compile error!

为了证实这个猜想,我们可以自定义一个扩展

extension UnsafeMutablePointer {
    init(_ from : UnsafeMutablePointer<T>) {
    // Swift 2: init(_ from : UnsafeMutablePointer<Memory>) {
        self = from
    }
}

它从另一个 相同类型 的指针初始化指针。 现在您的所有代码都可以按预期编译和工作。

你可以做的是使用withUnsafeMutablePointer():

legIntPtr = withUnsafeMutablePointer(&legInt, { [=13=] })

但请记住,编译器不会跟踪此指向的指针 对象作为参考,并可能破坏该对象。这就是为什么 这些指针是 "unsafe"。您通常应该使用指针 仅 withUnsafeMutablePointer() 闭包中。