【问题标题】:Why can't I pass an implicitly unwrapped optional as an UnsafeMutablePointer?为什么我不能将隐式展开的可选项作为 UnsafeMutablePointer 传递?
【发布时间】:2018-09-30 09:26:55
【问题描述】:

似乎 Xcode 9.3 确实修复了one issue I was having,但在 Swift 4.1 中,这段代码的后半部分仍然无法编译:

var obj: SomeClass!    ; class SomeClass {}

func inoutFunc(_: inout SomeClass?) {}
inoutFunc(&obj)     // works

func pointerFunc(_: UnsafeMutablePointer<SomeClass?>) {}
pointerFunc(&obj)  // <-- COMPILER ERROR

现在调用inoutFunc 没问题,但是调用pointerFunc 仍然给我一个错误:

无法使用类型为“(inout SomeClass!)”的参数列表调用“pointerFunc”

或者在原始上下文中:

无法传递“ActualClass”类型的不可变值?作为 inout 参数

类似于我的 Swift 4.0 问题(inoutFunc 也没有编译)如果我将声明更改为var obj: SomeClass?,那么第二个函数调用将毫无怨言地编译。

这是另一个与隐式展开的选项相关的挥之不去的 Swift 错误,还是这种UnsafeMutablePointer 的情况不会像现在的inout 版本那样工作?有没有相对干净的解决方法?


背景:

在实际代码中,pointerFunc 调用是一个 Apple 框架函数,它要么初始化实例,要么返回错误状态。

由于我已经guard AppleFrameworkInitializer(&amp;obj) == noErr else { /* … */ },我不想处理从临时可选项重新分配,或者必须在随后的所有代码中不断解开obj!

也就是说,这似乎是隐式解包选项的合法用例,我想知道为什么我仍然不能在这里使用。

【问题讨论】:

  • 假设这仍然是一个 Swift 错误,我在SR-3512 上添加了这个示例作为评论。
  • 另一个挥之不去的错误,恐怕。虽然它已经被修复(几乎可以肯定是由于最近的工作从类型系统中完全删除 IUO)——它在最新的开发快照中编译,因此将使其成为 4.2(最终从 master 重新分支是 4 月 20 日)。
  • 感谢 MartinR 和 Hamish 的测试!很高兴他们在 4.1 版本之后仍在取得进展……我想我现在将留下我的代码 TODO。 (如果有人想把它写出来,很高兴接受这个结果作为答案,否则我自己过几天就可以了……)
  • 我会在几秒钟内写出答案 :) 好消息是,至少从 Swift 4.2 开始,绝大多数 IUO 与 Optional 的不兼容问题都应该得到修复,因为现在 IUO 实际上是现在在类型系统中建模为 Optionals(以前它们被建模为具有特殊逻辑的单独类型,使它们看起来像 Optionals)。

标签: swift pointers optional inout


【解决方案1】:

恐怕这是另一个关于隐式解包选项 (IUO) 的挥之不去的错误。

虽然它已经被修复(几乎可以肯定是 the recent-ish work to completely remove IUOs from the type system 的结果)——它在最新的开发快照中编译,因此将使其成为 4.2(最终从 master 重新分支是 4 月 20 日)。

在 4.2 推出之前,一种可能的解决方法是使用转发计算变量,以便将 IUO 视为强可选类型:

class SomeClass {}

var obj: SomeClass!
var _optionalObj: SomeClass? {
  get { return obj }
  set { obj = newValue }
}

func pointerFunc(_: UnsafeMutablePointer<SomeClass?>) {}
pointerFunc(&_optionalObj)

(也就是说,假设您可以让指针指向一个临时值 - 即您不依赖于稳定或唯一的指针值,例如如果要使用它,您会这样做,因为例如,作为关联的对象键)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多