Sunday 11 June 2017

Optionals in Swift Programming

What is optional? When declaring variables in Swift, they are designated as non-optional by default. In other words, you have to assign a non-nil value to the variable. If you try to set a nil value to a non-optional, the compiler will say, “hey you can’t set a nil value!”.

var message: String = "Swift is awesome!" // OK
message = nil // compile-time error

An optional declaration doesn’t say “this is an String, which is optional”. It says, “this is an Optional, which may or may not hold an String”

Have you ever struggled with the various “?” and “!” symbols here and there in a Swift code? Or ever found yourself confused about the phrases like 
  • “Forced unwrapping”, 
  • “Optional unwrapping” or “Optional binding”,
  • “Automatic unwrapping” or “Implicit unwrapping”,  
  • “Nil coalescing”, 
  • “Implicit binding” or “Optional chaining”  (will see this later point of time)
You’re in the right place!

Optionals are a powerful feature in Swift language which come to solve the problem of non-existing values. Coming from Java and being passed through the hell of NPEs (Null Pointer Exception), I’m truly excited with this feature of Swift.

Forced Unwrapping:
We use this way in order to get the value of age we put an exclamation mark at the end of the variable.

var age: Int?
age = 23
print(age!) // outputs 23

This option is not a safe one because if age were a nil, it would crash the app, so we need to use a safest way to unwrap the optional Int value.

Optional unwrapping / Binding:
So this is the safest and preferred way to unwrap an optional, we say if age variable really contains a Int value meaning it is not a nil value then unwrap and assign it to myAge variable and that by the way myAge variable will hold an Int type and not an Int? type thus we can use it as it were a normal variable.
But if age contains a nil value then the execution flow won’t get to the if body which is great since we wouldn’t want to use nil.

var age: Int?
age = 23
if let myAge = age {
  print(myAge) // outputs 23

Automatic / Implicit unwrapping:
It is rare to use this way of unwrapping an optional but it is good to know when you encounter some code using it so it is simply putting the exclamation mark at the end of the type declaration, and then whenever we try to get the value of age, Swift will automatically will unwrap the optional for us giving us the value.

var age: Int! // here goes the exclamation mark
age = 23
print(age) // outputs 23

Nil coalescing:
Sometimes we want to use a default value when the optional is nil. Let’s take a look at this example:

let optionalInt: Int? = nil
var result: Int
if optionalInt != nil {
    result = optionalInt!
} else {
    result = 0
print("The result is \(result)")    // prints "The result is 0"

This could be reduced to a one line by using a ternary operator (the “?” below represents the ternary operator).

let optionalInt: Int? = nil
let result = optionalInt != nil ? optionalInt! : 0
print("The result is \(result)") // prints "The result is 0"

Nil coalescing allows us to shorten this even more, this just means (??) “If optionalInt is nil then use zero, otherwise use its unwrapped value”.

let optionalInt: Int? = nil
let result = optionalInt ?? 0

print("The result is \(result)")  // prints "The result is 0"

No comments: