Sometimes, when working with data, you will run into a situation where the data you are working with could either have a value, because some computation succeeded, or not, if something went wrong. In this lesson we will cover how Swift handles this scenario. It's time to learn about optionals!
1.Introduction3 lessons, 15:05
2.Foundational Concepts5 lessons, 43:51
3.Working With Collections3 lessons, 26:26
4.Controlling Flow7 lessons, 1:22:24
5.Functions5 lessons, 51:54
6.Creating Types6 lessons, 1:08:10
7.Conclusion1 lesson, 01:15
The next thing that I would like to take a few moments to talk about is the concept of an optional. Now, depending on other things you may have read, you may have noticed that optionals are usually covered a little bit further down the line after you've spent a little bit more time with the language. But I like to do it up front simply because it's something that you're going to run into quite often as a lot of the APIs within Swift, within the standard library and in other places throughout the different STKs depending on what you're targeting, whether it be Mac OSX or iOS we're going to deal a lot with optionals and you have maybe poked around a little bit. You might have said, I don't know what you're talking about optionals. This is a new concept to me. Well it actually isn't, so an optional is kind of likened, at least in my mind, to the topics of nullables or nulliable types in other languages, where a certain value can take on multiple options as far as values. It could either have the explicit value that you're working with or the explicit type of value that you're working with, or it could have well, no value at all or be null or nill. And that's how optionals are going to work within the Swift programming language. So let's take a look at how something like this might work. Now in the previous example I started to elude to in show you a simple example on how you could take a string value that actually looks like an integer and actually cast it or course it into becoming an actual integer and I did that by using a special function that comes along with the integer type, which is an int and then open and close parenthesis in which you pass in some sort of string value. So the way that this would work would be, I would have a, we'll just define a constant here and we'll say this is gonna be some number string like this and I will set this equal to the string of value five. Now if I wanted to convert this or cast this into the actual number five, the integer value five, I could then pass my sum number string into here, sum number string, and then I would obviously want to assign that to something I could say, let my number be equal to int, some number string, and then I could go on in my happy way and do whatever I wanted with it. I could maybe print out my number. We could save that and run, and then ultimately down in the console you're going to see that I get, well that's strange. I didn't get five I got an optional five. So what exactly is that? Well that is Swift's way of kind of creating another method of defensive programming for you, because in this case, there is really not a guarantee when you use this particular method or function of converting a string to an integer that this could actually work. What would happen if I were to, say, pass in something else instead of an actual number 5? Say I passed in my name and then I tried to run that, well, what, what's the results going to be, at that point, we're going to get a nil. But the interesting thing here is that I didn't get an error, nothing actually broke here. Now in many other languages doing something like this would absolutely result in some sort of error or exception. So, this is the way that Swift gets around them. So what's happening here is that once again, I'm gonna start to introduce some concepts that you've already learned, couple them with optionals and then show you some new things that are coming in the future. So what's happening here is that since we're not explicitly giving a type to my number, what it's doing behind the scenes is it's implicitly typing this, and so what's it's implicitly typing it is, well it's not implicitly typing it as an integer, because if I try to force this to be an integer we're going to very quickly see that this won't work. And you'll see an error pop up here, and if you'll take a look it's going to say the value of optional type ends with this goofy questions mark, and we'll come back to that in a second, is not unwrapped did you mean to use exclamation mark or exclamation point or question mark. Now this is a very strange thing if you never seen it before. It's very foreign but it is actually quite simple to understand. So what an optional actually is, is a mechanism by which you can wrap a certain value or a certain type in this protective layer called an optional. So what the implicit typing here is actually doing is it's making this an optional int and the way that we specify and optional type is by specifying the type name, in this case int and then appending onto the end of it a question mark. Now if I do that, the compiler's gonna be happy and everything is gonna continue to work. I can save this and run and I will once again get nil as my output. So, just kinda keep that in the back of your mind that if you ever are running into a scenario where you see something in an API or somewhere else where you see this kind of goofy question mark here, think to yourself, that's an optional which means whatever this function or method or whatever it is that I'm using, it can't guarantee the validity of the output or the input that's coming into it. So it can't necessarily guarantee that you're gonna get the actual value type out of it that you are expecting. So in this case, I'm running into such a problem where I'm actually passing in a string that does not represent a number into this function that's going to output, supposedly a number. So what does this buy for you? Well it buys a little bit of security, but how do we work with that security cuz this seems a little bit overwhelming. What if, what if I need to know if this is a valid number or not? How can I check that, or how can I get the actual value out? Because if I'm just getting nil here, so if I set this back to five, I could save this and run. Now instead of just getting a five back, I'm actually getting an optional five. But is that really a five? And the answer to that well, no, it isn't. So the way that we start to get around this is a couple of different ways. So, let's say at this point, that I wanted to continue to do a similar operation to this. So, one thing that I could be doing here, is I could be declaring this variable of my number to be an optional integer and that's absolutely fine. So then, I could come down here and I could say, my number is going to be equal to this and everything is going to work just fine. In order for me to actually take this optional, which is right now, remember it's a protective wrapper around, in this particular example an integer, but you could have these optionals wrapped around any sort of type that you're gonna run in to. What if I wanted to unwrap it and actually get the value out of it? So instead of getting this optional five, I wanted to get just the five. Well, in order to do that, I have to kind of tell the optional, just give me your value, unwrap yourself, give me your value. And in order to do that you need to do the opposite of defining an optional here with a question mark. You need to be a little bit more forceful and say, give me that value. And when we use force in language, at least in most common terminology, we use the exclamation point. So the way that we do that is we say exclamation point at the end of that particular variable that we're working with. So I can now save this and if I were to run it now, instead of getting my optional five I'm going to get an actual five. So that's kind of handy, so then couldn't I just maybe bypass that and maybe stick that exclamation point up at the top, maybe say unwrap it right away? Could I do something like that? Well, yes you absolutely can. So I could define this integer, this my number constant, to be an unwrapped integer so then when this operation completes, Swift is going to know that my number once this value unwraps. So it will unwrap it immediately for us, and then allow us to output so we could go ahead and run that. And this is going to work again. Once again, we'll get 5. But this is a very dangerous practice. Now, obviously, in this particular example I know that this is going to work, but in very large applications where I'm either getting input from other pieces of code somewhere else or maybe getting input from the end user, this could be very dangerous. Because once again, if this is passed in as something else like ABC and I try to run this, everything is gonna work fine at compile time, but at run time, we're gonna have a problem and we're actually going to get an error at this point. So what's another way that we could start to work around this to maybe check to see if something is valid or check to see if I'm actually getting a good and expected value here. It's actually pretty simple. There's a couple of different ways to do it. The first one is actually based on a topic that I'm going to, actually both of them are based on a topic that I'm going to cover a little bit later on, when we start getting on to controlling flow and conditional statements. But I think you're ready to at least understand a little of it now. So one thing that I'm going to do is, I'm going to say I want to do a conditional statement. I wanna check if something is true. So we're gonna talk about the if statements much more later on, but this is a nice little precursor into that world. So I wanna check to see if something is true and if it is true, then I wanna do some sort of operation. Well, one of the if statements or one of the things I can check here, is I could actually switch this back to an optional and I could say if my number is not equal to nill, now nill is a special value that just represents a lack of a value in this case. So what I could do is check to see if my number is not equal to nil and this is the not equal operator here, and if it truly is not nill, so at this point if this optional comes back and I'm getting a value that's an optional and if it's not equal to nil I could do something in here. I could print out my number and I could use the exclamation point to say unwrap that value and actually print out that number and then I could use an else statement here maybe. And I could do something like this instead of trying to print it out and printing out something nasty, I could print something a little nicer in here and say, you didn't provide an actual int. Something like that would probably work fine. So we'll go ahead and save that. So now if I were to run this application as abc, it's gonna say, oh, well, you didn't actually provide an actual int. So now I can check to see if my input coming in here is actually valid or not. And if it is valid, if I set this equal to 5, I could save and run this. And then we should get 5 out here. So that's the basic way for you to be able to check to see the validity of a value of whether it's an optional, whether it's an actual optional value that has a value, or if it's nil. So there you have it. That is the basic information around an optional and what an optional is, and how to use it and how to declare it. And the fact that it's simply just a wrapper around another type to allow you to be a little bit more safe in some of your conversions and things that you're doing within your applications and within other applications and how to actually deal with it and unwrap it to get out it's actual value.