Transcript from the "Null Safety" Lesson
>> I'm going to jump into chapter four, null safety. So let's try to analyze the idea first. So I'm going to add a couple of lines here so you don't see that. So when you create the variable in Swift, I am creating a variable. For example, let's do this.
[00:00:20] I'm going to create a class even if we haven't seen classes yet. But we create the class Person. We use code block and create the variable with a name, okay? And say the name is going to be a String. If I do this, it's giving me an error.
[00:00:36] It's saying, hey, class person has no initializer. By the way, an initializer is another name for a constructor. In Swift, we call constructors, initializer. But why is it saying this? Because it says that the property name has no initial value. So I actually need to receive that value in the initializer or set it in the initializer.
[00:01:03] It's complaining because if I say that the name is a string, I must have a string. It cannot be nil or null, in Swift we use nil. So actually, I cannot live without the value. It needs a value. But sometimes we have the situation where semantically, that value is optional.
[00:01:30] In that case, we said that with a question mark, okay? So at the end of the type, we'll use a question mark. So it can be a string or nil. It's called nil, not null here, okay? So now by default, it's going to be nil. And if you want, you can add value to it, okay?
[00:01:53] So on every type, I mean, you can also have a double. For example, it can have a coordinate, and say, okay, it's a double of two integers. And I can say, okay, it can also be null. It's optional, or I can have even optionals on each type. For example, the first one is mandatory and the second one is optional.
[00:02:18] So I can use these question marks on every type, okay? Saying that the value for the type is optional, okay? Does it make sense? For now it feels okay. It's not actually a big deal, it sounds cool. But then we start with some problems. For example, if I have a name, that it's going to be a string or nil, I cannot call a property or a method.
[00:02:48] For example, count is how you count characters on a string. By the way, it's also how you count items in a collection. It's dot count, not dot length. But it's saying, hey, no, I cannot give you the count, the amount of characters, because maybe the name is nil, okay, so we have a problem.
[00:03:11] Does it makes sense? There are two ways to solve the problem, because it says, hey, maybe it's nil, so maybe there are no characters. One solution is to use an exclamation mark. The exclamation mark will treat the optional as non-optional. Will actually say, okay, there is a value there, so go and get the amount of characters.
[00:03:39] What happens if it's nil? Like in this case, your app will crash because this is like in Java, the null pointer exception, okay? The difference here is that this is not an exception, we cannot trap it so easily. Actually, your app will crash. And if your app crashes on iOS at least, it will actually be closed.
[00:04:05] Probably you've seen that as a user both on Android or iOS, that you were using an app and then the app disappears magically, but that's actually a crash. So we should use this exclamation mark with a lot of care. Actually, it's kind of a bad practice to use it like this unless you know for sure as a developer, that if the execution gets into line 30, there is a value in that name, okay?
[00:04:38] Another option that we have is to use another operator is called the safe operator. It's question mark dot. Question mark dot will actually treat that, Optional as optional. And this is like asking, okay, if it's not nil, get the count, and if it's nil, return nil or do nothing, okay?
[00:05:10] So for example, what happens if I create a variable here, like this. I call the variable count, and I'm saying its name. Remember, here I'm using exclamation mark not question mark. So if I look at the type, it's actually an integer, okay? It's an integer, for sure. But if I use now, question mark, okay, instead of exclamation mark, if I see the type, look the difference.
[00:05:48] The type is integer optional. Why? Does anyone know why it has a question mark, that type? Because it can be nil, the name can be nil. If it's nil, there is no count. So if there is no count, there is no integer. So the type that is automatically inferred here, it's optionally integer.
[00:06:18] Okay, so that's another option that you have. So I'm going to create all the possible options. So this is called the safe operator. Then we have the explicit unwrap or optional unwrap. There is a question mark, like countForSure, like so. And also we have another operator that is useful for default values.
[00:06:46] Okay, so I will say, countOrDefault is equal to name.count. It's some kinda fun or 0. It's double question mark, okay? But here he's saying, hey, you need to do this So actually, this is actually verifying if the previous expression is not nil. If it's not nil, it's going to return that expression, if not, it's going to return to 0, the default value.
[00:07:25] Okay, so it's similar to the ternary operator. By the way, the ternary operator exist. So for example, countOrDefault2. I can say, if name?.count is not nil, then return name?.count if not 0. But you can see that this one is actually much better, it's the same. It's actually doing the same, okay?
[00:08:18] But then you will get it. So we can create variables, inside if expressions, with length, if length. So, I can create the variable like this, if let, let's say nonOptionalName = name. So this is what will happen, if let will create a variable, in this case a constant.
[00:08:47] An immutable variable within the scope of the if. So the scope of this nonOptionalName variable is just the if, okay? Not outside the if, so it's not available outside. I don't have this nonOptionalName. It doesn't exist, okay? It only exists within the if. So if I put it here, it's actually working now.
[00:09:14] And if I do .count, it works. So let's see what happens. The type of the name, it's actually a String optional. The type of nonOptionalName, it's a string, it's not optional anymore. Okay, so what's going on? This if is creating about a new variable, if the name is not nil.
[00:09:43] So that means that the else means that there is no name. Give me a minute. I already said that this is weird, okay? So what is doing this is creating a new variable is unwrapping the optional. And if it's nil, so if it was optional, it goes to the else.
[00:10:08] Okay, it goes to a false condition. So within the if now, we don't have optionals. We know that there is a value. And most of the time, we don't change the name, we do this. That's the part where it comes even weirder. So if let name = name actually creates a new local variable to the if with the same name, but now it's not optional.
[00:10:37] The deal here is that we are removing the optional. Does it make sense? So now there are two variables with the same name, but they have different scopes. We have one that the scope is the if and the other one that is the scope. So the one that is the inner scope is not optional.
[00:10:55] So then we don't need to mess with the exclamation mark, okay, or question mark, or default values, it becomes clearer with less, let's say, less symbols, yeah.
>> Yeah, with a difference.
>> We can always check that name is an object or not.
>> We don't know if it's in a string, so actually it's not an object.
[00:11:41] So you can always do this name not nil, but if you do this inside, you still need to mess with the exclamation mark. So actually, these two codes are the same. So these two blocks, these two ifs are doing the same thing. But the idea of using this if let is to make the code less symbolic so we don't have any exclamation mark or question mark with the if let.
[00:12:18] It's just that. You're not forced to use that, okay? It's just something that we have as a tool to work with options. You need to get used to that, okay? So it takes some time to get used to that if let, mostly when you're using the same variable name, okay, which is kind of why are we doing this when we are unwrapping the optional?
[00:12:42] And if there is no value, it goes to the else, that's the idea, yeah.
>> Jumping ahead of you, but would you use guards as well?
>> We have something known as guards, it's available, I will show you that later. We're not going to use today any guard, but just because you mentioned that, let me show you that.
[00:13:01] There is also another expression known as guard. Guard is more suitable for error management. So we'll check that the condition is met. For example, I know that, let's make the guard here, that it's not nil or here anyway. When we know it's not nil because I wanna get rid of the nil problem.
[00:13:24] So I can say that I need the name to be greater than 3. What we are, it's like an if, okay, but there are a lot of differences. First, we don't have a code block, there is no cold block for the true value. Actually, what we are saying is we actually nil this.
[00:13:49] We nil the count of characters or the amount of characters of this name to be greater than 3. We nil this. If that's not the case, we have the else. And on the else, we must throw an exception or return because there is no way to continue the execution.
[00:14:12] We can also do this, let count = name.count or something like that. And this is more advanced and advanced with topic to be honest, so it's part of answering the question. The only difference with the if is that when you do if let, the variable, the scope of the variable is the if.
[00:14:36] When you use guard, the variable, the scope of the variable is actually in this case, the outer scope, okay? So that's how guard works in Swift, okay? Anyway, we're going to see later that with Swift UI and that's our guard today, we don't have a lot of use cases for this.
[00:15:00] So we're not going to use guard later. But the guard must throw an exception or they must return in the else. So it's more for preconditions that must be defined. So these preconditions must be true because if not, I'm not going to continue executing this code.
>> Okay, it's around error management.
>> Thank you.
>> Okay, you are welcome. Any other question, yeah?
>> So when you're in the if let scope, if you do a return, not necessarily in the guard, but if you do a return, it's returning out of the let and also out of whatever it's-
>> Return always return in the function.
[00:15:44] So it works only if you have a function. So here if I use returns though, so maybe you're looking for break more than return that is available. Okay, so if you wanna break the current loop in a while, there are a couple of situations where we have break.
[00:16:02] You have four through also, there are some things. But typically, we are not going to use it mostly in Swift UI, mostly in Swift UI because Swift UI, we're going to see is more functional based. So it's using more functional priming ideas where we don't use this, okay?
[00:16:24] But if you're doing more classic UI kit development, yeah, maybe you have more of these situations.