Are implicitly unwrapped optionals truly optionals

2019-07-07 07:24发布

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

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

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

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

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?

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

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

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

That code was actually:

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

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

1条回答
forever°为你锁心
2楼-- · 2019-07-07 08:14

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).

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)

or

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

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

查看更多
登录 后发表回答