隐式展开的可选对象是真正的可选对象吗? [英] Are implicitly unwrapped optionals truly optionals?

查看:92
本文介绍了隐式展开的可选对象是真正的可选对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Swift 4.0, the following code doesn't compile:

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

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

Now I imagine that str is of type String? in actuality, and the Swift compiler seems to agree:

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

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

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

I can fix this by either changing the the variable to type String? or the function parameters to (_ s: inout String!) but I don't understand why I have to. Swift already seems to agree that var str : String! is "of type 'String?'" — so why won't it let me pass it in here?

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

Is there another option I can use to keep my variable implicitly unwrapped, but still pass it to a function that modifies an optional?

我试过someFunc(&(str?))只是让事情变得怪异-然后 Swift抱怨道:

I tried someFunc(&(str?)) and that just makes things weirder — then Swift complains:

无法传递类型为'String!'的不可变值!作为inout参数".

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

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

So str is a String? but can't be passed as a String?, while str? is a String!?!

该代码实际上是:

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

因此,也许Swift会在其错误消息中错误地说出参数的类型,而不是传递的值?

So maybe Swift is mistakenly saying the type of the parameter, rather than the value passed, in its error message…or something?

推荐答案

这是已知错误在迅速的编译器中. Hamish在评论中说,此问题已在Swift 4.1快照中修复,因此它可能会在下一个Xcode版本(9.3)中得到修复.

This is a known bug in the swift compiler. Hamish says in a comment this is fixed in a Swift 4.1 snapshot, so it may be fixed in the next Xcode release (9.3).

您可以通过摆脱隐式展开的可选(IUO)来解决此问题,无论如何都应避免.根据当前为什么是IUO的原因:

You can work around this by getting rid of the implicitly-unwrapped optional (IUO), which should be avoided anyway. Depending on why it's currently an IUO, either:

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

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

我强烈建议您首先使用,除非绝对必要,否则请避免强行展开.

I strongly recommend the first, avoid force-unwrapping unless absolutely necessary.

这篇关于隐式展开的可选对象是真正的可选对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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