Contact Us

Use the form on the right to contact us.

You can edit the text in this area, and change where the contact form on the right submits to, by entering edit mode using the modes on the bottom right. 


Oak Ridge, TN, 37830
United States

Swift-Snips

Variables & Conditionals

Wade Cantley

This pretty much had me scratching my head on day one.

Conditionals.  The ability to say "Hey, this is a variable, but... we are not sure what will go in it.. and it might be empty to".  So it is kinda like playing "lets make a deal" right?

There are some differences between them and they are slight but they are important when you get to using them because I am finding that I have to use them all over, especially in examples and tutorials where they don't exactly tell you why they are using them...  they just do.. sometimes.

So lets start with some code to add clarification.


This is where we prep the variable.  What is important to note is that doorNumber3 doesn't instantiate until it has something put in it.  But doorNumber2 and 3 do!  They both have "nil" in them.  The less verbose way of saying "NADA!" "ZIP" or "ZILCH" which is pretty much the response I got as a kid when asking if we had any cookies.

 

If we just printed this to the screen we would get: 

for doorNumber1... nil
for doorNumber2... nil
for doorNumber3...  an error.

So lets add some values.

// Playground - noun: a place where people can play

import UIKit


var doorNumber1: String?
var doorNumber2: String!
var doorNumber3: String

So if we add this to our playground, we can see that all the variables will display their content. But since we may not know if there is content, we really need to evaluate it first.

One way to evaluate is to simply put it in an "if" statement and check to see if it does or doesn't equal nil.

doorNumber1 = "Beef jerky?"
doorNumber2 = "A Bahama Trip!"
doorNumber3 = "Goat on a Leash"

As you can see, if it is an optional, you can evaluate it, but if it is NOT an optional, well the system throws an error and calls you dumb... in that overly technical way that Apple does oh so well.

Using this method you can't evaluate a variable that is not setup to potentially have a "nil".

While this method works great the output differs.  

If you use a "!" (aka: Bang)  like we did with doorNumber2 then it can evaluate it and unpacks the value in the process.  That is almost like setting up a variable and saying "it could be something or nothing, but I definitely want it unpacked if it is something"

However, doorNumber1 is conditional with a "?" (aka: Whuh?!") and on showing it's value it will state that it is an optional with a value.  After which it will need to be "unpacked" by throwing a Bang after the variable.

 

Another way to evaluate a variable is by using "Optional Binding Syntax" and it looks like this.

// This WORKS but it displays the variable as an Optional.

if doorNumber1 != nil {
    
    println("And behind door number 1 is ... \(doorNumber1)")
    
    // We need to "unpack" this optional by putting a BANG on it.
    println("And behind door number 1 is ... \(doorNumber1!)")
    
} else {
    println("And behind door number 1 is NOTHING! NIL! NADA!")
}


// This WORKS because it could be something or could be NIL
// Also note that it displays the actual value.

if doorNumber2 != nil {
    println("And behind door number 2 is ... \(doorNumber2)")
} else {
    println("And behind door number 2 is NOTHING! NIL! NADA!")
}


// This doesn't work because DoorNumber3 CANT be nil. So it errors.
/*
if doorNumber3 != nil {
println("And behind door number 3 is ... \(doorNumber3)")
} else {
println("And behind door number 3 is NOTHING! NIL! NADA!")
}

Here we are putting the result of the conditional variable into another variable and this automatically unpacks it if it is uses "?".  
SCORE!!

But that isn't real helpful if I want to use that variable outside of the "if" statement.

 

 

// Note that with "?" optional, checking it this way will unpack an optional 
//      into the new variable all while checking the result
if let openDoorNumber1 = doorNumber1 {
    println("My Very Own... \(openDoorNumber1)")
} else {
    println("Wah waaaaahhhh... nothing behind door 1")
}

// We also get back the results
if let openDoorNumber2 = doorNumber2 {
    println("My Very Own... \(openDoorNumber2)")
} else {
    println("Wah waaaaahhhh... nothing behind door 2")
}


//  This breaks because there is no need to check for nil, which is what this is doing.
/*
if let openDoorNumber3 = doorNumber3 {
    println("My Very Own... \(openDoorNumber3)")
} else {
    println("Wah waaaaahhhh... nothing behind door 3")
}
*/

Lastly we can use what is called the "nil-coalescing operator" which means that we can put a default value in place of a nil if nil exists.

Even if the variable isn't conditional, it can still be evaluated in this method so long as it has something in it.  

//----------------------------
// We can also use the "nil-coalescing operator" which is like combinging the IF statement.
// The BEST part is that you can use it on ANY kind of variable.  
// The prior checks are great but will error when a variable is not
// setup with ? or !.  But this works across all three types.
// That is until openDoorNumber3 has no value.  Since it can't be 
// nil, it can't do a check when it doesn't exist and will error.
let openDoorNumber1 = (doorNumber1 ?? "Nada")
let openDoorNumber2 = (doorNumber2 ?? "Nada")
let openDoorNumber3 = (doorNumber3 ?? "Nada")

println("You Win ....\(openDoorNumber1)")
println("You Win ....\(openDoorNumber2)")
println("You Win ....\(openDoorNumber3)")

And there you have it!  

3 ways to figure out whether a value has something in it, and how to handle what happens when it doesn't have something in it.

Swift is very type-strict even though it can infer type, I have found that casting between types as well as handling Conditionals has been challenging.