问题
The docs say: "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." I can copy the example and demonstrate this.
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 shows that UnsafeMutablePointer has the following initializer:
init<U>(_ from: UnsafeMutablePointer<U>)
, but when I try to use it like my function, the compiler error is Cannot find an initializer for type 'UnsafeMutablePointer<T>' that accepts an argument list of type '(inout UInt32)'
So,
- What's the direct way to get an
UnsafeMutablePointer<UInt32>
to legInt? - Why can’t I use the initializer as expected?
Thanks!
回答1:
I am a little bit speculating here, but the reason seems to be that
UnsafeMutablePointer<T>
has generic initializer
init<U>(_ from: UnsafeMutablePointer<U>)
where <U>
is unrelated to <T>
. It seems that the compiler cannot
infer the type <U>
in
legIntPtr = UnsafeMutablePointer(&legInt) //Compile error!
Just to confirm this conjecture, we can define a custom extension
extension UnsafeMutablePointer {
init(_ from : UnsafeMutablePointer<T>) {
// Swift 2: init(_ from : UnsafeMutablePointer<Memory>) {
self = from
}
}
which initializes the pointer from another pointer of the same type. Now all your code compiles and works as expected.
What you can do is use withUnsafeMutablePointer()
:
legIntPtr = withUnsafeMutablePointer(&legInt, { $0 })
But keep in mind that the compiler does not track this pointer to
the object as a reference and might destroy the object. That's why
these pointers are "unsafe". You should normally use the pointer
only inside the withUnsafeMutablePointer()
closure.
来源:https://stackoverflow.com/questions/29976346/why-can-t-i-initialize-a-swift-unsafemutablepointeruint32-with-myuint32-or