12.6 inout doesn't accept literals?

In section 12.6 we have the example code…

var error = "The request failed:"
func appendErrorCode(_ code: Int, toErrorString errorString: inout String) {
    if code == 400 {
        errorString += " bad request."
    }
}
appendErrorCode(400, toErrorString: &error)
print(error)

…with this note, “you cannot pass a constant or literal value into an in-out parameter.

But isn’t var error = "The request failed:" a String literal? And aren’t we passing it to the function?

error isn’t a String literal, it’s a variable - that’s why the code works. The book is telling you that you can’t do this:

appendErrorCode(400, toErrorString: "The request failed:")

"The request failed:" is a string literal, so the function can’t modify it.

If you want to pass in a string literal like that, then you need a function similar to the one in 12.7, where the value being returned is separate from the value passed in:

func appendErrorCode(_ code: Int, toErrorString errorString: String) -> String {
    var result = errorString
    if code == 400 {
        result += " bad request."
    }
    return result
}

Then you can say

var error = appendErrorCode(400, toErrorString: "The request failed:")
print(error)

or you could say

var error = "The request failed:"
error = appendErrorCode(400, toErrorString: error)
print(error)

You’d have the flexibility to pass in a string literal or a string variable, whichever you choose.

3 Likes

Aha. Thanks @JonAult. That makes perfect sense. I get it now. I think I was not understanding what exactly a String literal is.

Earlier in the book (2.1), referring to var numberOfStopLights = "Four" it says…

"How does it know that “Four” is an instance of String? Because the quotation marks indicate that it is a String literal.

Now I can see the String literal is just the "Four" part, not the whole line var numberOfStopLights = "Four".

1 Like