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?
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:
or
I strongly recommend the first, avoid force-unwrapping unless absolutely necessary.