隐式解包的期权是真正的期权吗?

时间:2018-02-15 19:03:17

标签: swift optional inout

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

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

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

  

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

我可以通过将变量更改为String?或将函数参数更改为(_ s: inout String!)来解决此问题,但我不明白为什么必须这样做。斯威夫特似乎已经同意var str : String!是“类型'字符串?'” - 那么为什么它不允许我在这里传递它?

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

我试过了someFunc(&(str?)),这让事情更加怪异 - 然后 Swift抱怨:

  

无法传递“String!”类型的不可变值作为inout参数“。

所以strString?但不能作为String?传递,而str?String! ?!

该代码实际上是:

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

所以也许Swift错误地在错误消息中说出参数的类型而不是传递的值......或者什么?

1 个答案:

答案 0 :(得分:1)

这是known bug in the swift compilerHamish 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!

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