Are implicitly unwrapped optionals truly optionals?

此生再无相见时 提交于 2019-12-10 20:59:45

问题


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:


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.



来源:https://stackoverflow.com/questions/48814508/are-implicitly-unwrapped-optionals-truly-optionals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!