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

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

概述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 iP Swift Optionals: When to use if let,when as? and as





Hi this isMarin- 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 calledageandheight. They are of the simple typeIntand can hold any integer number. Let’s see a quick code sample:

1 2 var age : Int = 35 let height : Int = 180

You declare a variableageby using the keywordvarand assign the value35. You might change your mind later on and assign another value,say36,and do that again and again.heighton the other sIDe is a constant – once you assign the value100to it – that’s it!

In both cases however you kNow thatIntcontains a value – an integer number. What youcannotdo is to assignnothingto 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 of0– you really should rather set the value tonothingormissing.

The case above would be a case where you would like to use anoptionaldata type.

Optionalin 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):

1 2 3 4 enum Optional : NilliteralConvertible { case None case Some ( T ) }

SoOptionalcan either containNone– and sinceOptionalis NilliteralConvertible you can guess that that’s the case for when you want to use nil for anoptionalvalue. The latter case defines thatoptionalcan 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 declareageandheightvariables that can hold and integer number or a nil.

1 2 var age : Int ? = nil var height : Int ? = 180

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:

1 var height : Int ? = 180

is actually equivalent to:

1 var height : Optional < Int > = Optional < Int > ( 180 )

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 thenavigationControllerproperty.

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

1 @H_974_404@ var navigationController : UINavigationController ? { get }

So let’s go back to our use case. If you kNowfor a factthat your vIEw controller will always have a navigation controller you can go ahead andforce unwrAPIt:

1 controller . navigationController ! . pushVIEwController ( myVIEwController , animated : true )

When you put a!behind the property name you tell the compilerI 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 thereisn’ta 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!:

1 controller . navigationController ? . pushVIEwController ( myVIEwController , animated : true )

What the?behind the property name tells the compiler isI 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. Noifchecks 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 anif letExpression.

When to use “if let”?

if letis 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:

1 2 3 4 5 if let nav = controller . navigationController { nav . pushVIEwController ( myVIEwController , animated : true ) } else { //show an alert ot something else }

Theif letstructure unwraps controller.navigationController (i.e. checks if there’s a value stored and takes that value) and stores its value in thenavconstant. You can usenavinsIDe the first branch of theif. Notice that insIDe theifyou don’t need to use?or!anymore. It’s important to realize thatnavis actually of typeUINavigationControllerthat’s not an Optional type so you can use its value directly. (If you remember in contrast the navigationController’s original type isUINavigationController?)

if letis 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 useif letyou code will looke like this:

1 2 3 4 controller . navigationController ? . hIDesbarsOnSwipe = true controller . navigationController ? . hIDesbarsOnTap = true controller . navigationController ? . navigationbarHIDden = false controller . navigationController ? . popToRootVIEwControllerAnimated ( true )

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 anif let:

1 2 3 4 5 6 if let nav = controller . navigationController { nav . hIDesbarsOnSwipe = true nav . hIDesbarsOnTap = true nav . navigationbarHIDden = false nav . popToRootVIEwControllerAnimated ( true ) }

Much nicer,isn’t it?

One final note –navin the above example is a constant. You can change propertIEs on it and call methods,but you can’t change the value ofnav. It’s worth mentioning that you can do something like that by simply usingif 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:) ).

1 2 3 4 5 6 7 8 //your custom vIEw controller class MyVIEwController : UIVIEwController { var lastUpdated : NSDate ? = nil } //in your master vIEw controller let myVC = MyVIEwController ( ) presentVIEwController ( myVC , animated : true , completion : nil )

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

1 controller . presentedVIEwController ! . Title = "New Title"

presentedVIEwControlleris of Optinal type UIVIEwController? so you can easily unwarp the value and use it. But how about if you want to change thelastUpdatedproperty,which you define inMyVIEwControllerand is not defined in UIVIEwController?

You can cast an Optional property by usingas?like so:

1 2 let myVC = controller . presentedVIEwController as ? MyVIEwController myVC ? . lastUpdated = NSDate ( )

as?trIEsto 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 useas?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,useas?if the cast Could fail in any possible way.

As opposite to a possible failing cast when you useas?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 usingas.

Let’s have a look as couple of examples when casting withasis 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:

1 let sheepCount = 71 / 2.0

Now sheepCount is aDoubleand 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 anIntlike so:

1 let sheepCount = 71 / 2.0 as Int

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 forasis when you are matching a pattern in aswitchstatement. In aswitchyou can always useasinstead of aas?since the pattern is matched only when the cast succeeds. For example if you dIDn’t kNow what typesheepCountwas – you can check that by passing it to a switch statement and try casting to different types in the different cases:

1 2 3 4 5 6 7 8 9 switch sheepCount { case let sheep as Int : println ( "\(sheep) found" ) case let sheep as Double : println ( "oops - fractional sheep!" ) default : break }

In each of thecasestatements the local,for that case,constant calledsheepis of a different type – in the former case it’s of typeIntand in the latterDouble.

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/

·

总结

以上是内存溢出为你收集整理的Swift Optionals: When to use if let, when ? and !, when as? and as全部内容,希望文章能够帮你解决Swift Optionals: When to use if let, when ? and !, when as? and as所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1075065.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存