Unwrapping Optionals More Concisely

Posted by Grego on January 11, 2015

When writing my previous entry about Learning Swift, the TDD Way I didn’t really know much of what I was doing. Now, just a few days later I’ve taken another crack at the String Calculator Kata.

One thing I didn’t like much was the way I was unwrapping optionals in swift. In swift, optional types are a way of specifying that a certain value might be nil.

From the Apple’s The Swift Programming Language:

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.

Previously, I had written a solution for my first single number unit test in the StringCalculator project:

  func add(var numberString: String) -> Int {
    if (countElements(numberString) == 1) {
      let numericValue: Int? = numberString.toInt()
      if numericValue != nil {
        return numericValue!
      }
    }

    return 0;
  }

Then I learned that I can cut it much shorter by using a let statement in the if statement, in place of a simple expression:

  func add(expression: String) -> Int {
    if countElements(expression) == 1 {
      if let intVal = expression.toInt() {
        return intVal;
      }
    }

    return 0;
  }

Also notice that I got rid of my surrounding parentheses. Since the let statement is not an expression you cannot wrap it in parens. Which leads me to believe I should drop my convention of wrapping my if statements with ().

It’s only one line shorter, but if you have many of these checks—which you probably should since Apple boasts this to be one of Swifts strong points—it will save a lot, and make the code easier to read.

Something else I found that you cannot do is combine the let statement with the logical && operator to add an expression:

  func add(expression: String) -> Int {
    //wrong. will not compile
    if countElements(expression) == 1 && let intVal = expression.toInt() {
      return intVal;
    }

    return 0;
  }

You can learn more from Benedikt Terhechte in his Swift optionals made simple article.

Now this begs the question, should I be using an optional return value for my add() method in the StringCalculator class? Post a comment below with your thoughts/feedback.