0 1 00:00:00,710 --> 00:00:05,000 Welcome to yet another Swift Deep Dive. In this episode, 1 2 00:00:05,000 --> 00:00:09,620 we're going to talk about Optionals (!?). And what the heck are "Optionals"? 2 3 00:00:09,620 --> 00:00:16,070 So we keep seeing these exclamation marks in question marks all over our code, especially when we find 3 4 00:00:16,070 --> 00:00:20,820 it from StackOverflow or when we see it in the Swift Documentation. 4 5 00:00:20,900 --> 00:00:25,270 Now what exactly does it mean and how do we use it? 5 6 00:00:25,310 --> 00:00:31,350 So in order to understand this better, I want to introduce you to our shed cat Fluffy. 6 7 00:00:31,370 --> 00:00:38,450 So this is our cat that we have to look after now, you and me. But we have to transport our cats and 7 8 00:00:38,450 --> 00:00:41,180 we're going to do that in a cardboard box. 8 9 00:00:41,210 --> 00:00:47,210 So Fluffy goes into the box and we're pretty sure that currently, we have definitely a real cat in the 9 10 00:00:47,210 --> 00:00:47,660 box. 10 11 00:00:47,710 --> 00:00:48,110 Meow. 11 12 00:00:48,530 --> 00:00:54,990 But let's say that during the hectic time of moving, we also accidentally popped a bottle of poison into 12 13 00:00:55,010 --> 00:00:56,960 the same box as Fluffy. 13 14 00:00:57,620 --> 00:01:06,200 So now we package it up and we kind of moved around in the van, shake it around, and the poison bottle 14 15 00:01:06,200 --> 00:01:11,090 might be broken. And we now basically have an optional cats, 15 16 00:01:11,120 --> 00:01:11,550 right? 16 17 00:01:11,570 --> 00:01:14,840 We have a cat with a question mark at the end of it. 17 18 00:01:14,840 --> 00:01:23,510 We don't know if Fluffy is dead or alive. And if we were to force open or force unwrap our box and see 18 19 00:01:23,510 --> 00:01:29,810 what's inside, well, we might discover that, indeed, we do still have Fluffy. She's alive and well and she's 19 20 00:01:29,810 --> 00:01:36,830 smart enough to not eat the poison because, you know, we're good at rearing cats. But we might also find 20 21 00:01:36,830 --> 00:01:39,110 that Fluffy is no more, 21 22 00:01:39,200 --> 00:01:43,310 she got tempted by the poison. It smelt like Play-Doh, 22 23 00:01:43,310 --> 00:01:46,820 so she had a little bit. And now Fluffy is dead. 23 24 00:01:46,820 --> 00:01:53,040 So we might actually have no cat, which in programming lingo, we would call nil. 24 25 00:01:53,090 --> 00:01:56,100 This is essentially how optionals work. 25 26 00:01:56,160 --> 00:02:00,110 There's frequently cases where you need a container, 26 27 00:02:00,140 --> 00:02:04,820 so a variable, that might often need to start out containing no data. 27 28 00:02:05,180 --> 00:02:11,090 Let's say that you had a field in your app where you were going to save the user's username. Well, before 28 29 00:02:11,090 --> 00:02:18,440 they actually created that username variable is going to be nil. But then, hopefully, at a later date, 29 30 00:02:18,500 --> 00:02:24,470 when you need to use the username to display it on screen or to use it in some way, then you're hoping 30 31 00:02:24,470 --> 00:02:26,150 that the user has ready filled it in. 31 32 00:02:26,180 --> 00:02:34,340 So it does, in fact, have a value. In order to represent this uncertainty in Swift, we use something called 32 33 00:02:34,430 --> 00:02:35,500 optionals. 33 34 00:02:35,510 --> 00:02:41,620 So you've seen that when we create a variable, we can specify a data type at the point of creation. 34 35 00:02:41,780 --> 00:02:48,350 So we could add a colon and then add the type of data that this variable or this container or cardboard 35 36 00:02:48,350 --> 00:02:50,410 box is going to store. 36 37 00:02:50,540 --> 00:02:57,170 But then we can add a question mark at the end of our data type to turn it into a completely different 37 38 00:02:57,170 --> 00:03:01,650 data type and it becomes a optional data type. 38 39 00:03:01,670 --> 00:03:08,780 So now this variable hardness can store a string or it can simply be empty. 39 40 00:03:08,780 --> 00:03:13,810 It could have no data or store nil. In a blank playground, 40 41 00:03:13,810 --> 00:03:21,190 I'm going to create a new variable and I'll call it player1Username and I'm gonna set it to be a 41 42 00:03:21,190 --> 00:03:23,140 string data type. 42 43 00:03:23,140 --> 00:03:30,850 And at the very beginning of the game before any player has even gotten the chance to assign themselves 43 44 00:03:30,880 --> 00:03:31,780 a username, 44 45 00:03:32,070 --> 00:03:35,510 well, this variable is not going to contain any data, 45 46 00:03:35,530 --> 00:03:39,820 right? It's going to contain no data or nil. 46 47 00:03:39,820 --> 00:03:47,140 And as soon as you try to run this, because our variable is mostly meant to hold data of string data 47 48 00:03:47,140 --> 00:03:49,430 types, it gives us an error. 48 49 00:03:49,660 --> 00:03:56,200 So we can't just simply take a normal variable container and try to give it no data. 49 50 00:03:56,980 --> 00:03:59,140 What can we do instead? 50 51 00:03:59,140 --> 00:04:07,750 Well, we could instead create a variable called player1Username. and instead of assigning it to a string 51 52 00:04:07,750 --> 00:04:12,580 data type, we give it a string with a question mark at the end. 52 53 00:04:12,580 --> 00:04:15,390 So now it's a optional. 53 54 00:04:15,580 --> 00:04:25,720 And now I can quite easily say that actually this player1Username, it has no data stored 54 55 00:04:25,720 --> 00:04:32,320 in it. But at a later date, I'm going to ask the player, "Well, what is your username?" 55 56 00:04:32,320 --> 00:04:43,550 And they'll give me a username which might-- Let's say, "jackbauerisawesome," so now I have a value inside 56 57 00:04:43,610 --> 00:04:46,410 my optional player1Username. 57 58 00:04:46,550 --> 00:04:54,590 So if I was to print my player1Username at this point, you will see a optional string being printed, 58 59 00:04:54,830 --> 00:04:58,670 So the word "Optional," and then a string. 59 60 00:04:58,670 --> 00:05:05,360 So how can we turn it from an optional, which it is at the moment, which you can see right here, but you 60 61 00:05:05,360 --> 00:05:09,020 can also check by holding down the optional Alt key, 61 62 00:05:09,140 --> 00:05:13,130 you can see that it's data type is clearly an optional string. 62 63 00:05:13,160 --> 00:05:20,150 Well, we could simply just force unwrap it. So we unwrap our box and accept whatever the consequences 63 64 00:05:20,150 --> 00:05:24,800 may be and we try to use the unwrapped version. 64 65 00:05:24,800 --> 00:05:33,580 Now, if I run my code, again, you can see that my optional has become a normal string again. 65 66 00:05:33,890 --> 00:05:44,210 And in fact, if I simply go ahead and create a new variable called unwrappedP1Username and I set 66 67 00:05:44,210 --> 00:05:51,950 it equal to player1Username unwrapped, then you can see that when I check the data type of this 67 68 00:05:51,980 --> 00:05:56,090 unwrappedP1Username, it's now back to a normal string. 68 69 00:05:56,120 --> 00:06:04,880 So it's no longer an optional anymore because I have overridden the safety check. So the safety check 69 70 00:06:04,940 --> 00:06:13,010 is there to prevent us from crashing and burning when we try to do something with a nil value, so a null 70 71 00:06:13,010 --> 00:06:21,330 value. Let's say, if at some later point, I changed my player1Username to, again, equal nil. 71 72 00:06:21,350 --> 00:06:28,160 So let's say that the player has reset their username and, in fact, I'm going to common out this line 72 73 00:06:28,160 --> 00:06:31,190 just to make it a bit clear what's going on here. 73 74 00:06:31,190 --> 00:06:35,920 So we started out by creating a container that can hold nil values, 74 75 00:06:35,930 --> 00:06:41,990 so an optional string data type. And it started out being nil, but then we gave it a value, but then we 75 76 00:06:41,990 --> 00:06:47,860 remove the value and player1Username no longer contains any data on line 10. 76 77 00:06:47,870 --> 00:06:56,960 So now if we try to print it and we unwrap it forcibly, saying that "I am so sure that this will definitely 77 78 00:06:56,960 --> 00:06:59,400 always have data. Computer, 78 79 00:06:59,420 --> 00:07:07,470 listen to your master, which is me the programmer. Just do as I say." And we run it and then all it's going 79 80 00:07:07,470 --> 00:07:14,150 to do is crash. Because if we have a nil value that we're trying to do something with, say, we're trying 80 81 00:07:14,150 --> 00:07:17,830 to add two to nothing. It doesn't make any sense 81 82 00:07:17,840 --> 00:07:28,340 if we try to print nothing, if we try to do anything with a nothing data. It's like taking thin air 82 83 00:07:28,340 --> 00:07:29,910 and trying to do something with it, 83 84 00:07:29,960 --> 00:07:34,970 so that's when our app would crash. In order to prevent this from happening, 84 85 00:07:35,060 --> 00:07:37,400 we can enact some safety checks. 85 86 00:07:37,640 --> 00:07:40,640 The first safety check is, actually, your brain. 86 87 00:07:40,640 --> 00:07:48,350 The reason why a lot of things are optionals are that you are reminded that some of these values can 87 88 00:07:48,350 --> 00:07:50,820 have nil as its value. 88 89 00:07:50,840 --> 00:07:57,040 You want to be able to check through the code and make sure that it won't ever become nil. 89 90 00:07:57,050 --> 00:08:04,550 Now another way of doing this is we can actually just explicitly check to see if player1User name 90 91 00:08:04,580 --> 00:08:07,240 does not equal nil. 91 92 00:08:07,310 --> 00:08:10,240 So that's what that exclamation mark equals mean, 92 93 00:08:10,280 --> 00:08:12,920 means does not equal. 93 94 00:08:12,920 --> 00:08:14,330 And in that case, 94 95 00:08:14,360 --> 00:08:21,440 well, then we could use it and we can unwrap it forcibly. Because now, even though player1Username is 95 96 00:08:21,440 --> 00:08:26,900 equal to nil, our app is no longer going to crash because it's going to bypass the line that would cause 96 97 00:08:26,900 --> 00:08:30,190 an issue because this is not true. 97 98 00:08:30,200 --> 00:08:36,710 Player1 is, in fact, equal to nil. Then we're going to skip the line and we're not going to crash our 98 99 00:08:36,710 --> 00:08:41,320 app by using a piece of data that's nil. 99 100 00:08:41,390 --> 00:08:49,910 Now, there's a really fun comic that somebody once made on "If programming languages were weapons," and 100 101 00:08:50,000 --> 00:08:59,280 one of the biggest problems with a lot of older languages like Java is this idea of a NullPointerException. 101 102 00:08:59,390 --> 00:09:03,650 So this is essentially the same as what we've been talking about. 102 103 00:09:03,670 --> 00:09:11,090 So it says that Java is a belt-fed 240G automatic weapon where sometimes the belt has rounds, sometimes 103 104 00:09:11,090 --> 00:09:11,650 it doesn't. 104 105 00:09:11,690 --> 00:09:18,890 So sometimes it has data, sometimes it's equal to nil. And when it doesn't and you try to fire it, then 105 106 00:09:18,890 --> 00:09:22,860 you get an NullPointerException or you get an error like we did, 106 107 00:09:23,030 --> 00:09:24,500 and the gun explodes and you die. 107 108 00:09:24,620 --> 00:09:31,490 So this is one of the biggest problems with some of these older languages. And the way that Swift was 108 109 00:09:31,490 --> 00:09:37,550 designed is to be a safer language. So the gun doesn't explode in your face and you actually have 109 110 00:09:37,550 --> 00:09:39,080 a fun time using it. 110 111 00:09:39,230 --> 00:09:45,340 But in order for it to work, we have to understand when we're using an optional and to make sure that 111 112 00:09:45,430 --> 00:09:51,550 if we are unwrapping it with an exclamation mark, that we're certain, that it's never going to be equal 112 113 00:09:51,550 --> 00:09:58,080 to nil. If we're not certain, then we should probably check for it and to prevent our app from crashing, 113 114 00:09:58,540 --> 00:10:05,220 so that lines, where we're unwrapping, are optional, are protected by an "if" statement. 114 115 00:10:05,590 --> 00:10:12,480 Now, in later lessons, we're going to dive deeper into some other fancy things that you can do with optionals, 115 116 00:10:13,000 --> 00:10:15,570 such as optional chaining and optional binding. 116 117 00:10:15,640 --> 00:10:23,050 But for now, I just wanted to introduce you to the idea of a nil value that a variable can actually contain 117 118 00:10:23,380 --> 00:10:25,090 no data at all. 118 119 00:10:25,090 --> 00:10:33,940 And the idea that if you tried to do something with nil, then your program will likely crash and optionals 119 120 00:10:34,000 --> 00:10:40,720 are there to safeguard us from these situations, first, by making us think about whether if it could be 120 121 00:10:40,720 --> 00:10:41,600 nil 121 122 00:10:41,650 --> 00:10:45,880 and, second, by getting us to protect against those scenarios. 122 123 00:10:45,940 --> 00:10:51,790 So now that you've learned a bit more about optionals, it's time to complete the assignment that is on 123 124 00:10:51,850 --> 00:10:58,780 Beginning Optionals. And on the next lesson, we're going to head back into building our app. 124 125 00:10:58,780 --> 00:10:59,260 our app.