3

I think I'm confused about the concept of 'unwrapping' an optional value, and any guidance would be much appreciated!

According to the Swift Programming Language Guide, an optional requires unwrapping before it can be used, unless it is implicitly unwrapped using an !.

From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l:

let possibleString: String? = "An optional string."

println(possibleString!) // requires an exclamation mark to access its value

whereas

let assumedString: String! = "An implicitly unwrapped optional string."

println(assumedString) // no exclamation mark is needed to access its value

However, in Xcode, I can do the following and still print the value of an optional string:

let teamname: String? = "Liverpool!"

println("Come on \(teamname)")

What am I missing?

Cezary Wojcik
  • 21,745
  • 6
  • 36
  • 36
wavers
  • 39
  • 1
  • 3
  • 1
    See my answer [here](http://stackoverflow.com/questions/24034483/what-is-an-unwrapped-value-in-swift/24034551#24034551). Also, string interpolation automatically unwraps your object. – Cezary Wojcik Jun 04 '14 at 14:34
  • 1
    That's an incredibly clear explanation, so thanks, but I'm afraid I'm still a little confused. Is it the bottom part of that answer - i.e. the "difference between the first case and the second two cases is that the second two cases will give you a runtime error if optionalSquare is set to nil"? – wavers Jun 04 '14 at 14:38
  • 1
    I threw in a ninja edit that you might have not caught in the comment - string interpolation automatically unwraps your object. – Cezary Wojcik Jun 04 '14 at 14:40
  • I wrote an article about optionals that may be of some help. See the "rough edges" section for your question specifically about string introspection. https://medium.com/@rrridges/swift-optionals-a10dcfd8aab5 – Matt Bridges Jun 04 '14 at 14:40
  • @CezaryWojcik Thanks, I didn't know that! However, the string still unwraps even if I just write *println(teamname)* – wavers Jun 04 '14 at 14:42
  • The `println` function seems to be pretty smart about handling optionals in general. String interpolation basically just does `print(teamname)` when it comes across `\(teamname)`. – Cezary Wojcik Jun 04 '14 at 14:44

2 Answers2

2

An optional requires unwrapping, but you don't always have to do it yourself.

var teamname: String? = "Liverpool"
println("Come on \(teamname)")

In this case, the string interpolation will check the optional then unwrap it and add its value to the String. If the Optional is nil, it will add "nil" to the String instead.

In order to access the properties and methods of String you will have to explicitly unwrap it. If you don't know if it is nil or not, you should check with an if statement.

if teamname != nil {
    var newName = teamname!.capitalizedString
}
UglyBlueCat
  • 439
  • 1
  • 7
  • 22
Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
2

First of all, an optional requires unwrapping only if you are using it somewhere that does not allow an optional. (e.g. assigning a String? to a String)

var optionalString: String? = "Some string"
var absolutelyAString: String = "Another string"
// absolutelyAString = optionalString // Error. Needs to unwrap
absolutelyAString = optionalString! // OK. 

"Unwrap" basically means to "guarantee that the value is not nil". Just think of it as casting to a non-nullable type.

Second, println() accepts optionals just fine but because it checks your variable for you. If the value of your variable is nil, it prints "nil"; otherwise it prints the string implemented by the Streamable, Printable, or DebugPrintable protocols.

John Estropia
  • 17,460
  • 4
  • 46
  • 50