为什么我不能用 (&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)'
所以,
- 获取
UnsafeMutablePointer<UInt32>
到 legInt 的直接方法是什么?
- 为什么我不能按预期使用初始化器?
谢谢!
我有点猜测,但原因似乎是
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()
闭包中。
文档说:"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)'
所以,
- 获取
UnsafeMutablePointer<UInt32>
到 legInt 的直接方法是什么? - 为什么我不能按预期使用初始化器?
谢谢!
我有点猜测,但原因似乎是
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()
闭包中。