Xcode Beta 5 was released with several good changes. I don’t want this to just be a “What’s new in Xcode Beta 5” post, because once Beta 6 is released, much less the real language, the only point for a post like that is history. So I am mostly going to talk about my favorite addition to Xcode 6 about optionals, with a short mention of a change that affects it. This great operator is still available in Swift 2.2 (Xcode 7.3) as well!
Nil Coalescing Operator
I did not see this one coming, but I do like it. It basically is a way to easily return an unwrapped optional, or a default value. As with many other parts of optionals, this operator is composed of question marks. Below is a simple example:
var someOptional: Int? = nil var aDefaultValue = 42 var theAnswer = someOptional ?? aDefaultValue
Since someOptional is nil (we didn’t set it to a valid Int yet), theAnswer will of course be 42.
Apple’s iBook shows that the nil coalescing operator is shorthand for a ternary operator. While I can use the ternary operator and it is a short and concise way of writing a simple conditional, I usually have to look it up just to be sure, so for simplicity, I am going to compare it to what the ternary operator itself is shorthand for:
if (someOptional != nil) { theAnswer = someOptional! } else { theAnswer = aDefaultValue }
That is effectively what the nil coalescing operator is doing. Upon writing that, I can see why they chose to use the ternary operator, much shorter, and didn’t need me to write “theAnswer =” twice . Nonetheless, I still find it clearer to read. For the sake of historical significance, this is from the release notes, and appears to be the function definition for the nil coalescing operator:
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T { switch optional { case .some(let value): return value case .none: return try defaultValue() } }
That is from Open Source Swift’s code. It is a bit different from the first version, but mostly to move @autoclosure to its new place, and the ability to handle throwing errors. There is a slight modification, the “Some” and “None” are lowercase in the Open Source repository, but that is probably just how it looks internally. There is also a version of this in the standard library that handles the error handling with the T type marked as optional. Since the optional is actually an enumeration (as mentioned in my post Swift Optionals – Declaration, Unwrapping, and Binding), it being a switch statement internally is more likely. I did not know exactly what autoclosure did, but Jameson Quave did, so to quote him here, “the right-hand side takes basically any expression (any closure, except you don’t need to specify it’s a closure, the @autoclosure keyword turns it in to one).” See his original article at Swift’s Nil Coalescing Operator In Xcode 6 Beta 5. We have not really talked about closures yet, but they are one of the big additions to Swift, and they are basically self-contained code blocks. I would say they are kind of like functions, but able to be passed around like they were a variable, but it turns out, according to Apple’s iBook, functions are a special type of closure.
One other thing to note is that the second term, the “aDefaultValue”, is lazily evaluated. If it was a function there instead of a variable, it would not run the function unless the someOptional was nil. If it isn’t, then it just uses the unwrapped form of the variable, and just goes to the next line of code. That makes sense to me, better to not waste time evaluating something you won’t use.
Change to Optional protocol conformance
There was a breaking change to how optionals are handled in Swift. You may have noticed earlier in the if statement explanation of the nil coalescing operator, that I checked it against nil. Previously, optionals conformed to the LogicValue protocol (which was later renamed BooleanType). That meant you could use an optional as if it were a boolean (if there was a value, it was true, if there was a nil, it was false). That is no longer the case, the optional must be compared against nil instead. This unfortunately invalidated some of the slides from WWDC, but they did say there would be a lot of changes, and not necessarily have source compatibility between seeds.
That being said though, optional binding still works with the “if let” syntax. Optional chaining works as well, but if it is in an if statement, it must either be optionally bound, or checked against nil.
Conclusion
That is how the nil coalescing operator works. It is basically an easier to read ternary statement, which itself is a more concise if statement. Each of those analogies though are apparently covering up a switch statement. Abstraction!
With changes coming to Swift every few months, I’m always going back to check my previous posts, and updating them when necessary. The price we pay for blogging on the frontier.
Also, while it is unlikely that you have seen my blog before Jameson’s, if that somehow is the case, check out his blog at http://jamesonquave.com/blog/. He definitely knows his Swift stuff and has definitely been helpful to the new Swift community.
I hope you found this article helpful. If you did, please don’t hesitate to share this post on Twitter or your social media of choice, every share helps. Of course, if you have any questions, don’t hesitate to contact me on the Contact Page, or on Twitter @CodingExplorer, and I’ll see what I can do. Thanks!
Sources
- The Swift Programming Language – Apple Inc.
- Swift’s Nil Coalescing Operator In Xcode 6 Beta 5
- Xcode 6 Beta 5 Release Notes