Wednesday, 24 September 2014

Swift ?? ! ? (an excalmation explanation question)

Yesterday's exploration using Swift to access the Pinterest API was interesting and instructive. I glossed over some interesting details to focus on looking at the functional objectives of getting an end result rather than some of the Swift constructs. Today I thought it would be good to just walk through some of the syntax and concepts that were used and I haven't had a chance to note down cohesively.

This is really an opportunity to make a little reference review for myself of some Swift syntax features around Optionals.

So, kicking off, writing anything in Swift using the Cocoa APIs seems to require quite a bit of using quotation and exclamation marks. What's that all about? These are called Optionals and provide a language facility for describing types and handling variables that can have either a value or are 'unset'.  This idea has been around for a long time as 'tri-state' logic in digital circuits. C-sharp has the concept of nullable types built into the language which allow variables to hold a value or null and are represented by a type defintion T? The variable then can be checked against null before using. Swift brings this into the language along with a bunch of other useful features.

One of the usual ways of coming across this concept is with pointers in C++, where an object pointer is typically assumed (or set) to be null until the class is instantiated and set to the object pointer. In this case the pointer can be considered to point to null or the value of an object. Code then checks for null before using the object. Obviously this can only be used with objects in C++, Swift and C-sharp extend the concept of having a null/nil value to any type.  In Swift, these are called optionals and are written as follows:

var myOptional:Int?

This will be implicitly assumed to be the value nil until it is assigned to. Also, when using the variable, it must be checked against to ensure it is non-nil before using. In Swift-speak this is known as unwrapping. There are a few ways of doing this, we'll step thorugh them. Firstly, the obvious way is to check to see if the value is nil or not before using:

if myOptional != nil
{
   // use myOptional
}

Now that we're assured that the optional does indeed contain a value (e.g. it's not nil) the value can be 'unwrapped' using an exclamation mark as follows

// use myOptional
println("the value = \(myOptional!)")

In this case we're using the Swift string interpolation features to put the variable into the string. The syntax of 'implicitly unwrapping' an optional by adding an exclamation mark can be used where we're certain that the variable is non-nil and can safely use it e.g.

var myValue:Int = myOptional!

Another way of doing this is also to define a type that once it has been set will never be given a nil value, it's sort of like defining a const. In this case the exclamation mark is used in the type definition:

let anotherValue:Int! = 2_000

Swift also provides a short-hand way of doing this without explicitly putting an exclamation mark in if and while clauses as follows:

if let myValue = myOptional
{
}

Another way of unwrapping an optional (that I didn't use yesterday) is to use the 'Nil Coalescing Operator' which allows setting either the unwrapped value or an alternative value in the case that the optional value is nil. The Nil Coalescing Operator is written as a double quotation mark and can be used as follows:

var newValue:Int = myOptional ?? 404

In this case if myOptional is nil, then newValue will be set to 404. The Nil Coalescing Operator can be written in terms of the ternary conditional operator as follows:

a ?? b         is equivalent to        a != nil ? a! : b 

So, that explains the ! and ?s, but I think they were used a bit more than that, right? Well spotted, yes! Swift puts this concept in pretty deep. Most of the examples in the JSON code previously were using the concept of Optional Chaining. This is the idea of being able to call and query prorperties, methods and subscripts on optionals that might be nil. Optional Chaining is achieved by placing a question mark after the method, property or subscript, similar to how the exclamation mark is used to implicitly unwrap an optional value.

I haven't got time just now to go through this, but wanted to make sure that I'd referenced it to explain some of the usage of ? in the examples yesterday.

Lastly, the other concept uses extensively yesterday was the optional form of the downcast operator as?. In this case what is happening is that we know the type that the object needs to be downcast to, but we're not sure if the variable is nil or not and want to preserve that typing.





No comments:

Post a Comment