swift - 隐式展开的可选值真的是可选值吗?

标签 swift option-type inout

在 Swift 4.0 中,以下代码无法编译:

var str: String!
func someFunc(_ s: inout String?) {}
someFunc(&str)

现在我想象 str 实际上是 String? 类型,Swift 编译器似乎同意:

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

我可以通过将变量更改为类型 String? 或将函数参数更改为 (_ s: inout String!) 来解决此问题,但我不明白为什么我必须。 Swift 似乎已经同意 var str : String! 是“'String 类型?'”——那么为什么它不让我在这里传递它呢?

我可以使用另一个选项来隐式展开我的变量,但仍然将它传递给修改可选的函数吗?

我尝试了 someFunc(&(str?)),这只会让事情变得更奇怪 — 然后 Swift 提示:

Cannot pass immutable value of type 'String!' as inout argument".

所以 str 是一个 String? 但不能作为 String? 传递,而 str? 是一个 String!?!

该代码实际上是:

var str: String!
func someFunc(_ x: inout String!) {}
someFunc(&(str?))

所以 Swift 可能在其错误消息中错误地说明了参数的类型,而不是传递的值……或者什么?

最佳答案

这是一个 known bug in the swift compiler . Hamish says in a comment这已在 Swift 4.1 快照中修复,因此可能会在下一个 Xcode 版本 (9.3) 中修复。

您可以通过摆脱隐式解包可选 (IUO) 来解决这个问题,无论如何都应该避免。根据它目前是 IUO 的原因,要么:

var str: String?
func someFunc(_ x: inout String?) {}
someFunc(&str)

var tmp: String?
func someFunc(_ x: inout String?) {}
someFunc(&tmp)
let str = tmp!

我强烈推荐第一种,除非绝对必要,否则避免强制展开。

关于swift - 隐式展开的可选值真的是可选值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48814508/

相关文章:

ios - 是否有 WWDC 2019 session 视频摘要?

ios - UIImagePickerController 关闭后,UICollectionView 不会重新加载数据()

ios - 从 UITableViewRowAction 触发 segue

java - orElseThrow 比 if(obj == null) 更好吗?

swift - NSTableView 绑定(bind)在 mac OS Swift 上不起作用

java - 删除 map 条目会导致 map 条目中的对象引用可选更改

arrays - 更新通过引用传递的数组中的项目

swift - Inout 不使用 SubClass 对象抛出无法将不可变值作为 inout 参数传递

swift - Inout in swift 和引用类型

java - Swift 的 "implicitly unwrapped optionals"与 Java 的整数 "autoboxing"有何不同?