3

While reading the The Swift Programming Language, I came across this snippet:

You can use if and let together to work with values that might be missing. These values are represented as optionals. An optional value either contains a value or contains nil to indicate that the value is missing. Write a question mark (?) after the type of a value to mark the value as optional.

// Snippet #1
var optionalString: String? = "Hello"
optionalString == nil

// Snippet #2     
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

Snippet #1 is clear enough, but what is happening in the Snippet #2? Can someone break it down and explain? Is it just an alternative to using an if - else block? what is the exact role of let in this case?

I did read this page, but still a little confused.

Community
  • 1
  • 1
rgamber
  • 5,749
  • 10
  • 55
  • 99

3 Answers3

8
if let name = optionalName {
   greeting = "Hello, \(name)"
}

This does two things:

  1. it checks if optionalName has a value

  2. if it does, it "unwraps" that value and assigns it to the String called name (which is only available inside of the conditional block).

Note that the type of name is String (not String?).

Without the let (i.e. with just if optionalName), it would still enter the block only if there is a value, but you'd have to manually/explicitly access the String as optionalName!.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • Sorry, but can you explain the last line: you'd have to manually/explicitly access the String as optionalName!. A little ambiguous for me! Also, same block can be written as `if optionalName { greeting = "Hello, \(optionalName) " } right? – rgamber Jun 04 '14 at 06:08
  • Maybe this helps: http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark-mean-in-the-swift-language?rq=1 – Thilo Jun 04 '14 at 06:09
  • Thanks! The answer with the link makes it much clear! – rgamber Jun 04 '14 at 06:14
  • I don't think the last sentence is right. Using let doesn't make it optional binding. You can try `let stringNumber = "123;" let numberOption = stringNumber.toInt();numberOption!`. numberOption is still an optional and you need to force unwrap it with '!' – dalef Jun 04 '14 at 06:55
  • @dalef: You don't have an `if` in there. – Thilo Jun 04 '14 at 06:57
  • that's my point. should be without the if, not without the let. 'if name = optionalName { greeting = "Hello, \(name)" }' gives you compile time error of undeclared name instead – dalef Jun 04 '14 at 06:57
  • Well, you need both. The question (as I read it) was "why do I need the let, why can't I just use if alone". – Thilo Jun 04 '14 at 06:58
4
// this line declares the variable optionalName which as a String optional which can contain either nil or a string. 
//We have it store a string here
var optionalName: String? = "John Appleseed"

//this sets a variable greeting to hello. It is implicity a String. It is not an optional so it can never be nil
var greeting = "Hello!"

//now lets split this into two lines to make it easier. the first just copies optionalName into name. name is now a String optional as well.
let name = optionalName

//now this line checks if name is nil or has a value. if it has a value it executes the if block. 
//You can only do this check on optionals. If you try using greeting in an if condition you will get an error
if  name{
    greeting = "Hello, \(name)"
}
Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
  • So why can't `optionalName` be used directly. Why is it copied to `name` first? – rgamber Jun 04 '14 at 06:06
  • It actually can be used directly. It doesn't really matter in this example but there are some advantages to not calling it directly every time. I actually had the same question myself: http://stackoverflow.com/questions/24004897/why-use-an-extra-let-statement-here – Connor Pearson Jun 04 '14 at 06:07
  • 2
    The reason for the `if let name = ...` idiom is that accessing the value of an optional variable when it's `nil` is a runtime error. Using this construction lets you write code that can't have that kind of error, since the block of the if statement doesn't get evaluated if `optionalName` is nil. – Nate Cook Jun 04 '14 at 06:34
3

String? is a boxed-type, variable optionalName either contains a String value or nothing(that is nil).

if let name = optionalName is an idiom, it unboxes the value out of optionalName and assign it to name. In the meanwhile, if the name is non-nil, the if branch is executed, otherwise the else branch is executed.

shucao
  • 2,224
  • 1
  • 13
  • 7