为什么我不能将隐式展开的可选内容作为UnsafeMutablePointer传递? [英] Why can't I pass an implicitly unwrapped optional as an UnsafeMutablePointer?

查看:100
本文介绍了为什么我不能将隐式展开的可选内容作为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆