1

I'm new to swift and now learning from this book that is called The Swift Programming Language. In the book there is an example:

enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
    switch self {
    case .Ace:
        return "ace"
    case .Jack:
        return "jack"
    case .Queen:
        return "queen"
    case .King:
        return "king"
    default:
        return String(self.rawValue)
    }
}
}

And here is the part I don't understand:

if let convertRank = Rank(rawValue: 3){
    let description = convertRank.simpleDescription()
}

I tried change the code above to this:

let convertRank = Rank(rawValue: 3)
let description = convertRank.simpleDescription()

Basically, I have just removed the if statement, but then an error occurs: Value of optional 'Rank?' not unwrapped; did you mean to use '!' or '?'?

Why do I have to use an if statement? And I don't really understand what does the error message say.

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
Ming An
  • 155
  • 9
  • There are [several](http://stackoverflow.com/questions/25799529/value-of-optional-type-string-not-unwrapped) [similar](http://stackoverflow.com/questions/29373958/swift-error-value-of-optional-type-double-not-unwrapped) [questions](http://stackoverflow.com/questions/25662595/value-of-optional-type-cgfloat-not-unwrapped-error-in-swift). Did they not answer your question? – Marty Aug 31 '15 at 05:08

2 Answers2

2

if let is a special structure in Swift that allows you to check if an Optional holds a value, and in case it does – do something with the unwrapped value.

In your case:

if let convertRank = Rank(rawValue: 3){
    let description = convertRank.simpleDescription()
}

The if let structure unwraps Rank(rawValue: 3) (i.e. checks if there’s a value stored and takes that value) and stores its value in the convertRank constant. You can use convertRank inside the first branch of the if. Notice that inside the if you don’t need to use ? or ! anymore.

In your second case:

let convertRank = Rank(rawValue: 3)
let description = convertRank.simpleDescription()

You can unwrap convertRank this way:

let description = convertRank!.simpleDescription()

Trying to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

But below code will work same as if let:

let description = convertRank?.simpleDescription()

And program will not crash if convertRank is nil.


More Explanation:

Community
  • 1
  • 1
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
  • Thank you for the interpretation. This really helps me understand the error, but I have one more question. Do we always use "?" instead of "! "? Is there any advantage to use "!"? – Ming An Aug 31 '15 at 05:23
0

Because it's an Optional and you have to unwrap it before using. You can read about Optionals here.

let description = convertRank?.simpleDescription() would work.

Community
  • 1
  • 1
Maysam
  • 7,246
  • 13
  • 68
  • 106