Another cool new feature of the Swift 2 language is the
guard statement. Guards were added to Swift in order to allow developers to reduce the amount of nested
if statements in their code. We can now get rid of deep nesting in a structured, easily understandable way.
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 final topic in this section that I would like to cover before we jump into a demo application, has to do with a brand new feature of the Swift 2.0 language. And that has to do with the guard statements. So what exactly is the guard statement and what is it for? Well, let's start off by writing a very simple application here, that's going to represent a lot of bad code that we see out in the wild. We'll just start by writing a simple function, and it'll be called do something, and it will take in a couple parameters. We'll just say we have a val1, which is an optional Int, we'll have val2, which is also an optional Int. And we really don't need a return value. This is just a very simple example. So let's say we've written this particular function and there are a lot of, say, business rules around what are supposed to happen with these multiple values. So, the first thing that we're probably gonna have to do is some sort of validation, some sort of checking to make sure that the values are meeting the business rules, before we continue doing some sort of calculations or whatever business processing it is we're working on. So typically, within swift on what we have wind up doing is checking the value to see if they meet some sort of criteria in a positive way. So one thing we could do in this case, and we can come in and we could start doing some if let statements like we've seen before. So we could say, if let maybe number is going to be equal to val1. And we could also break out another new trick of Swift 2.0 and that's optional binding. So we could say, we want number to be equal to value but we only want it to be equal to the value where val1 is actually greater than zero. So maybe that's a business rule. So we wanna assign value, and we wanna assign value to number only in the instances where val1 is greater than zero, maybe that's some sort of business rule. And if that succeeds then we'd wanna come down here and maybe do the next check, maybe that has something to do with what val2. We could say let val or maybe let key be equal to val2, but we only want that to happen where val2 is maybe less than 100 or something. And you kinda get the picture here of what's going on. We're doing a lot of validations based on some sort of business rules that have been given to us. And typically, you would see something like this and we could continue creating this very nested tree of if statements which gets extremely ugly and very unwieldy to be able to work with. But then ultimately, we get down all through these successes and we can come down and do something with number. Maybe we could do let sum = number + key or something along those lines, whatever the process is necessary for us to do to be able to finish this function. Now, we can clean this up a little bit and one thing that we've kind of learned over the years is instead of doing this positive checks to make things get nested, we could invert that. We could make checking for the negatives in this case and we could say, all right, well, if the number is not greater than zero or if it's less then zero, then we'll continue or something or we'll dump out or something like that. We'll try to reduce the nesting here but unfortunately, it can be kinda complicated if you're not used to checking for negative scenarios. If you're programmed to look at the positive scenarios, then you're gonna wind up with this kinda nested bit of code here. Well, what the guard statement does is it allows us to reduce our nesting. And as you'll see here in just a moment, it'll let us do something else. So, if I wanted to continue doing this processing, I'd have to do all of my logic within these if lets because the binding here that we're doing only makes these values here. Number and key available within the scope of these if statements. So if I drop down out of that nested if and I wanted to get access to key I don't have access to it, it doesn't exist outside of that scope. I could still get a number here. But then if I try to drop out another line and try to go outside of that one, I don't have access to number anymore. I don't have access to key. So I'm kinda limited. I'm forced to keep those things in here. So what the guard statement's going to do, is it's going to do a couple of different things. It's going to allow me to reduce the nesting that I have going on in here. And it's going to increase the scope in which my variables are actually accessible. So I'm gonna get rid of this bit of code, and I'm going to use the guard key word. And actually, it should be referred to as the guard else because what this is ultimately going to do, is it's kind of going to flip the if statement on it's head and do the negative check that we just kind of discussed in a positively, if that makes any sense. But let's go through the example and I'll show you what I mean. So we're going to use a guard statement, and what we're going to do is we're gonna do a very similar operation. We're going to guard, and we're gonna do some sort of conditional check here, so we can once again do the same thing we were doing. We can say let number = to val1 where val1 > 0. And then at the end of a guard statement you have to have an else. And then within this else block, you have to handle any anything that doesn't fall into this scenario, into this positive scenario. And within the L-statement, you have to actually break your control flow. Which means, typically, one of two things. I could either do a return statement in here, I could put other statements in here as well. I could log something, I could write something to a database, do whatever I had to do for clean up. And then I will ultimately have to do a return statement, I can also put a throw in here, and I could throw an exception. Some type of an error if I wanted to. But ultimately, whatever you put in here, has to end with you getting out of this particular function, or out of this enclosure. So for this case, we'll just simply do a return, because obviously, something didn't work right here. The number was not be able to set to val, because the value was maybe less than zero or equal to zero or something like that. So as you can see now, I can drop down to the next line and I could do my next check. I can say guard let key = to val2, where val2 is maybe And once again we'll do our L statement and we'll do our, return. So as you can see now, I'm able to check these conditions in a positive way and not have to flip them and make them negative. And I can continue flowing down and I don't have to continually nest those if statements. So that's the first benefit. The next benefit is that I also, now down here because of the scope, I get access to both number and key. So I'm not creating a limited scope for these variables to live in, say inside some brackets. I'm actually able to access them anywhere so I can say something like var some = number + key or whatever I had to do ultimately and then we would be done with our application. So as you can see, the guard statement has kind of introduced the capability of us to be able to reduce nesting of if statements, in a positive way instead of having to look at the negative scenarios. And then it increases the scope of the variables that I optionally bind to or that I bind to within my let statement. So it does a couple of different things for us. It helps us to clean up our code a little bit and then ultimately increases our scope.