I'm going through the swift docs, and in the optional segment, it talks about using the question mark -- ?
-- to signify variables that might be nil. This can be used in an if statement to check for nil, but in the docs they assign the optional to a new variable in the conditional. Is there a reason for this?
For Example, it is presented in the docs similar to this:
// Declare an optional string (might be nil)
var optionalString: String? = "Hello"
// Assigns optionalString to new variable before checking if nil
if let string = optionalString {
println("\(optionalString) is not nil!")
}
else {
println("\(optionalString) is nil")
}
However, this runs just fine for me in tests:
var optionalString: String? = "Hello"
// Assigns optionalString to new variable before checking if nil
if optionalString {
println("\(optionalString) is not nil!")
}
else {
println("\(optionalString) is nil")
}
Is there a reason to assign optionalString
to a new variable string
in the conditional statement?
Optionals are in the core of Swift and exist since the first version of Swift. An optional value allows us to write clean code with at the same time taking care of possible nil values. If you're new to Swift you might need to get used to the syntax of adding a question mark to properties.
If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. This just means putting an exclamation mark at the end of the variable. Optional("Hello, Swift 4!")
How to declare an Optional? You can simply represent a Data type as Optional by appending ! or ? to the Type . If an optional contains a value in it, it returns value as Optional<Value> , if not it returns nil .
An optional value either contains a value or contains nil to indicate that the value is missing.
Take a look at the section on Optional Chaining in the docs. In the example you cite, there's not much difference. But in other cases, an if-let
construction lets you get at an unwrapped value that comes from a series of optional references and method calls, without using implicit unwraps that can crash your app if you haven't considered all the possible bindings for a value in a chain.
It's also useful if you want to avoid recomputing a value. You can use it in a lot of the same ways you'd use an assignment in a conditional in (Obj)C (remember if (self = [super init])
).
For example, if the optional being tested comes from a computed property:
var optionalName: String? {
get {
if checkTouchID() {
return "John Appleseed"
} else {
return nil
}
}
}
var greeting = "Hello!"
if optionalName != nil {
greeting = "Hello, \(optionalName)"
}
Paste that into a playground, along with a stub implementation of checkTouchID()
that returns true
, and you'll immediately see in the results area that the optionalName
getter is executing twice. (This would be a problem in a more realistic scenario, because you probably don't want code like this to implicitly checkTouchID()
or downloadFromServer()
or billApplePay()
twice.) If you use an if-let
construction instead, you'll only execute the getter once.
In a series of chained optionals (like if let johnsStreet = john.residence?.address?.street
in the docs linked above), you don't want to rewrite the whole chain in the body of the if
statement, much less recompute it.
I think the purpose of that assignment was to demonstrate the use of "let" within the if conditional clause. I don't see a meaningful difference between the provided code and your own.
From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/il/jEUH0.l
“If the optional value is nil, the conditional is false and the code in braces is skipped. Otherwise, the optional value is unwrapped and assigned to the constant after let, which makes the unwrapped value available inside the block of code.”
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With