为什么我不能将隐式展开的可选内容作为UnsafeMutablePointer传递? [英] Why can't I pass an implicitly unwrapped optional as an UnsafeMutablePointer?
问题描述
似乎Xcode 9.3确实解决了我遇到的一个问题,但是在Swift 4.1中,该代码的后半部分仍然无法编译:
It seems that Xcode 9.3 does fix one issue I was having, but in Swift 4.1 the second half of this code still doesn't compile:
var obj: SomeClass! ; class SomeClass {}
func inoutFunc(_: inout SomeClass?) {}
inoutFunc(&obj) // works
func pointerFunc(_: UnsafeMutablePointer<SomeClass?>) {}
pointerFunc(&obj) // <-- COMPILER ERROR
对inoutFunc
的调用现在可以了,但是对pointerFunc
的调用仍然给我一个错误:
The call to inoutFunc
is now fine, but the call to pointerFunc
still gives me an error:
无法使用类型为((inout SomeClass!)''的参数列表调用'pointerFunc'
Cannot invoke 'pointerFunc' with an argument list of type '(inout SomeClass!)'
或在原始上下文中:
无法传递"ActualClass"类型的不可变值?作为inout参数
Cannot pass immutable value of type 'ActualClass?' as inout argument
类似于我的Swift 4.0问题(其中inoutFunc
也未编译),如果我将声明更改为var obj: SomeClass?
,则第二个函数调用将在没有投诉的情况下进行编译.
Similar to my Swift 4.0 issue (where the inoutFunc
didn't compile either) if I change the declaration to var obj: SomeClass?
then the second function call compiles without complaint.
这是另一个与隐式解开的Optionals相关的挥之不去的Swift错误吗?还是不希望这种UnsafeMutablePointer
情况像现在的inout
版本那样起作用?有相对干净的解决方法吗?
Is this another lingering Swift bug related to Implicitly Unwrapped Optionals, or would this UnsafeMutablePointer
situation not be expected to work like the inout
version now does? Is there a relatively clean workaround?
背景:
在实际代码中,pointerFunc
调用是一个Apple框架函数,它可以初始化实例或返回错误状态.
In the actual code, the pointerFunc
call is an Apple framework function which either initializes the instance or returns an error status.
由于我已经guard AppleFrameworkInitializer(&obj) == noErr else { /* … */ }
,所以我不想处理从临时选件中重新分配的问题,也不必在后面的所有代码中不断地解包obj!
.
Since I already guard AppleFrameworkInitializer(&obj) == noErr else { /* … */ }
, I don't want to deal with re-assigning from a temporary optional, or have to constantly unwrap obj!
in all the code that follows.
也就是说,这似乎是隐式展开的可选"的合法用例,我想知道为什么我仍然不能在这里使用它.
That is, this seems like a legitimate use case for Implicitly Unwrapped Optionals and I'm wondering why I still can't use one here.
推荐答案
恐怕这是围绕隐式展开的可选对象(IUO)的另一个挥之不去的错误.
I'm afraid this is another lingering bug around implicitly unwrapped optionals (IUOs).
尽管它已得到修复(几乎可以肯定是由于完全从类型系统中删除IUO )–它会编译到最新的dev快照中,因此将其变为4.2(从master最终分支到4月20日).
It has already been fixed though (almost certainly as a result of the recent-ish work to completely remove IUOs from the type system) – it compiles in the latest dev snapshots, and therefore will make it into 4.2 (final re-branch from master is April 20).
在4.2发行之前,一种可能的解决方法是使用转发计算变量,以便将IUO视为强的Optional类型:
Until 4.2 rolls around, one possible workaround would be to use a forwarding computed variable in order to treat the IUO as a strong Optional type:
class SomeClass {}
var obj: SomeClass!
var _optionalObj: SomeClass? {
get { return obj }
set { obj = newValue }
}
func pointerFunc(_: UnsafeMutablePointer<SomeClass?>) {}
pointerFunc(&_optionalObj)
(也就是说,假设您可以将指针指向一个临时值–即,您不依赖于指针值是稳定或唯一的,例如,如果要使用该值,则为例如,作为关联的对象键)
(that is, assuming you're okay with having the pointer point to a temporary value – i.e you're not relying on the pointer value being stable or unique, such as you would be if this were to be used, for example, as an associated object key)
这篇关于为什么我不能将隐式展开的可选内容作为UnsafeMutablePointer传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!