Swift Optionals: When to use if let, when ? and !, when as? and as

Hi this is Marin - the author of Touch Code Magazine, I hope you are enjoying my tutorials and articles. Also if you need a bright iPhone developer overseas  contact me - I do contract work.  Here's my LinkedIn profile

It seems everybody is in love with Swift, but since Optionals are a rather advanced concept the Swift code I see published on the Internet tends to rather randomly unwrap Optionals. And to be honest I haven’t seen a good blog post to clearly explain in plain text when to unwrap in what way. So I thought I’d write one today.

So let’s start by a quick review what Optionals are.

What are Optionals

Consider your plain old data types just as the one you used in your Objective-C (or PHP, Javascript, etc.) code. Let’s say you have two variables called age and height. They are of the simple type Int and can hold any integer number. Let’s see a quick code sample:

You declare a variable age by using the keyword var and assign the value 35. You might change your mind later on and assign another value, say 36, and do that again and again. height on the other side is a constant – once you assign the value 100 to it – that’s it!

In both cases however you know that Int contains a value – an integer number. What you cannot do is to assign nothing to that variable – nil.

For example if those pieces of data represent an employee profile in a company database, for some records you might not know the height of the employee – in that case you shouldn’t set a value of 0 – you really should rather set the value to nothing ormissing.

The case above would be a case where you would like to use an Optional data type.

Optional in fact, what many people don’t realize, is just an enumeration defined in Swift’s standard library and topped with some syntax sugar. The enumeration looks like this (abbreviated):

So Optional can either contain None – and since Optional is NilLiteralConvertible you can guess that that’s the case for when you want to use nil for an Optional value. The latter case defines that Optional can hold a value of type T – any type T you’d like.

So for an Optional<Int> – it can contain either nil or the Int value. Very simple and easy. So let’s use Swift’s syntax sugar ? and declare age and height variables that can hold and integer number or a nil.

By adding a ? immediately after the data type you tell the compiler that the variable might contain a number or not. Neat! Notice that it doesn’t really make sense to define Optional constants – you can set their value only once and therefore you would be able to say whether their value will be nil or not.

To make it crystal clear what’s going on when you use Optionals let’s look at what’s going on behind the scenes in the above example. The line:

is actually equivalent to:

It looks very easy once you know what’s going on there, right? The ? symbol you add to datatypes to declare them as Optinal is just syntax sugar that does translates into the code above.

Okay, now that I hope you have a good idea what an Optional data type is, let’s have a look at how to use those types in code.

When to use ? and when !

Let’s imagine you have a simple iPhone app – a UIKit based application. You have some code in your view controller and you want to present a new view controller on screen on top of your existing one. You decide to push the new one on screen via a navigation controller.

As you, hopefully, know every ViewController instance has a propertynavigationController. If you are building a navigation controller based app this property of your app’s master view controller is set automatically and you can use it to push or pop view controllers. If you use a single app project template – there won’t be a navigation controller created automatically for you, so your app’s default view controller will not have anything stored in the navigationController property.

I’m sure you already guessed that this is exactly a case for an Optional datatype. If you check UIViewController you will see that the property is defined as:

So let’s go back to our use case. If you know for a fact that your view controller will always have a navigation controller you can go ahead and force unwrap it:

When you put a ! behind the property name you tell the compiler I don’t care that this property is optional, I know that when this code executes there always will be a value store so treat this Optional like a normal datatype. Well isn’t that nice? What would happen though if there isn’t a navigation controller to your view controller? If you suggestion that there always will be a value stored in navigationController was wrong? Your app will crash. Simple and ugly as that.

So, use ! only if you are 101% sure that this is safe.

How about if you aren’t sure that there always will be a navigation controller? Then you can use ? instead of a !:

What the ? behind the property name tells the compiler is I don’t know whether this property contains nil or a value, so: if it has value use it, and oterwise just consider the whole expression nil. Effectively the ? allows you to use that property just in the case there is a navigation controller. No if checks of any kind or castings of any sort. This syntax is perfect when you don’t care whether you have a navigation controller or not, and want to do something only if there is.

Perfect! But how about if you want to do somethinge else in case there wasn’t a navigationController? For example show an alert box to tell the user something.

Then you would use an if let expression.

When to use “if let”?

if let is a special structure in Swift that allows you to check if an Optional holds a value, and in case it does – do something with the unwrapped value. Let’s have a look:

The if let structure unwraps controller.navigationController (i.e. checks if there’s a value stored and takes that value) and stores its value in the nav constant. You can use navinside the first branch of the if. Notice that inside the if you don’t need to use ? or !anymore. It’s important to realize that nav is actually of type UINavigationControllerthat’s not an Optional type so you can use its value directly. (If you remember in contrast the navigationController’s original type is UINavigationController?)

if let is useful also in another case. Imagine that instead of a single method call you want to do more stuff with your navigationController. If you do not use if let you code will looke like this:

This code works but you need to unwrap the property 4 times and the code gets quite repetitive. It’s much cleaner and nicer (and faster) to unwrap the value once in an if let:

Much nicer, isn’t it?

One final note – nav in the above example is a constant. You can change properties on it and call methods, but you can’t change the value of nav. It’s worth mentioning that you can do something like that by simply using if var. It works the same way, but instead of an unwrapped constant you have an unwrapped variable and you could change its value if you wanted to so.

This brings us to the final use case I wanted to cover when using Optional data types – type casting.

When to use as? and when as

Let’s continue working with our imaginary UIKit app. Let’s assume you present a new modal view controller on screen (e.g by using presentViewController(_, animated:, completion:) ).

You define a custom view controller, which has an extra property called lastUpdated. Let’s suppose you wanted to change this property once the controller is presented. You can access the presented controller via the presentedViewController property on the main view controller:

presentedViewController is of Optinal type UIViewController? so you can easily unwarp the value and use it. But how about if you want to change the lastUpdatedproperty, which you define in MyViewController and is not defined in UIViewController?

You can cast an Optional property by using as? like so:

as? tries to cast the value to the given type and if it doesn’t succeed returns a nil. That’s why the resulting type is always an optional value. You are forced to use as? also when the cast is not guaranteed to succeed – for example if you are trying to cast an AnyObject or Any value to a concrete class.

So, long story short, use as? if the cast could fail in any possible way.

As opposite to a possible failing cast when you use as? there’s also the cases where you are 101% sure that the cast will succeed and in those cases you can omit the ? and just cast by using as.

Let’s have a look as couple of examples when casting with as is useful.

Consider you are calculating the number of sheep on a farm. Through some weird math you get a fractional value, like in this example:

Now sheepCount is a Double and contains the value 35.5. Since you need an integer number and since casting from a Double to an Int is safe (e.g. will alwaus succeed by cutting off the floating part of the number) you can just cast the result to an Int like so:

In this case since the expression is casted to an Int type – also the sheepCount constant type will be Int (in contrast in the previous example sheepCount was of type Double)

Another case for as is when you are matching a pattern in a switch statement. In aswitch you can always use as instead of a as? since the pattern is matched only when the cast succeeds. For example if you didn’t know what type sheepCount was – you can check that by passing it to a switch statement and try casting to different types in the different cases:

In each of the case statements the local, for that case, constant called sheep is of a different type – in the former case it’s of type Int and in the latter Double.

Where to go from here?

I hope that was a detailed introduction to how to use Optionals. Remember that is important not only for your code to work, but also for you to know how does it work :)

If you are interested to learn more about everything that has to do with Swift, consider reading my colleagues Colin Eberhardt and Matt Galloway’s book “Swift by Tutorials“.

By the way Swift by Tutorials is part of the iOS8 Feast where you can send a single tweet and have a chance to win some of the prizes in a total value of over $10,000. Read more here – iOS8 Feast.

Thanks for reading and I’ll see you next time.

The post was originally published on the following URL:  http://www.touch-code-magazine.com/swift-optionals-use-let/

 

  ·

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值