swift - 为什么我不能将隐式解包的可选项作为 UnsafeMutablePointer 传递?

标签 swift pointers option-type inout

似乎 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 的调用仍然报错:

Cannot invoke 'pointerFunc' with an argument list of type '(inout SomeClass!)'

或者在原文中:

Cannot pass immutable value of type 'ActualClass?' as inout argument

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

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


背景:

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

因为我已经guard AppleFrameworkInitializer(&obj) == noErr else {/* … */},我不想处理临时可选的重新分配,或者必须不断在后面的所有代码中解包 obj!

也就是说,这似乎是 Implicitly Unwrapped Optionals 的合法用例,我想知道为什么我仍然不能在这里使用它。

最佳答案

恐怕这是另一个围绕隐式解包选项 (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)

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

关于swift - 为什么我不能将隐式解包的可选项作为 UnsafeMutablePointer 传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49928472/

相关文章:

ios - 如何从嵌入在不同 UINavigationController 中的多个 UIViewController 切换到一个 UIViewController

c++ - 处理访问 NULL 指针

swift - 如何在 SwiftUI 中使用属性化字符串

Swift 枚举超出范围

c - 通过 char 指针输出不正确

java - 将缺少的 xml 属性解码到可选的 java 对象

swift - 删除强制展开

fortran - 可分配 Intent(inout) 参数可以是可选的吗?

用户输入时的 Swift 格式文本字段

c - 数组作为带参数的函数?