Reputation: 11026
From the Swift book, that Apple has released we can make optional value by putting ? to a variable like
var optionalString: String? = "Hello"
optionalString == nil
and also written that “You can use if and let together to work with values that might be missing.”
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
greeting = "Hello, \(name)"
}
written above code for checking that optional value is nil or not, it will not go inside if optionalName is nil.
but same can be done without using the let like
if optionalName {
greeting = "Hello, \(optionalName!)"
}
why in book it is suggested to use the let?
Upvotes: 9
Views: 5044
Reputation: 2048
I'm coming from the ruby world where "Hello, (optionalName)" would return "Hello, ", i.e. if optionalName is nil then interpolate the empty string. Currently if optionalName is nil Swift prints "Hello, nil" and if it's not nil it prints something like "Hello, Optional("John")". When using "Hello, (optionalName!)" then it prints "Hello, John" and if optionalName is nil it causes a runtime error. For rubyist stumbling onto this wondering how to achieve ruby behaviour:
let EMPTY_STRING = ""
var greeting = "Hello, \(optionalName ? optionalName! : EMPTY_STRING)"
Upvotes: -1
Reputation: 41226
Your confusion arises because you're using println to display optionalName, and println is smart enough to handle optional values and unwrap them as necessary. If you used the hypothetically similar code:
if optionalName {
greeting = "Hello, " + optionalName
}
you would get an error because you can't concatenate a String and a String? You have three ways around that
First, you can use conditional unwrapping after you do the check, but this is inefficient because if you reference optionalName more than once, since you have to unwrap it each time.
if optionalName {
greeting = "Hello, " + optionalName?
}
You can improve that by using forced unwrapping, since you've already done the test and know that optionalName can never be nil. This is still inefficient if you reference optionalName multiple times, as each time the unwrapping must be done.
if optionalName {
greeting = "Hello, " + optionalName!
}
Lastly, you can use the if let syntax to test and unwrap all at the same time. Name is safe to use because it will be of type String, not String?
if let name = optionalName {
greeting = "Hello, " + name
}
Upvotes: 2
Reputation: 726569
Your second code snippet is functionally equivalent to the one from the book. However, the book suggests using let
to avoid multiple unwrapping of the optional value.
Since you are checking optionalName
for being empty, it is safe to assume that you plan to use it inside the conditional block. When you do so, Swift would need to unwrap the optional value from optionalName
again, because the variable remains optional.
When you do the assignment of optionalName
to name
in the let
declaration, the name
constant that you get back is not optional. This saves you the unwrap inside the if
statement.
Upvotes: 14