In Swift, extensions allow us to add functionality to existing types—a very useful construct! Swift 2 has extended the extension mechanism by allowing use to apply extensions not just to concrete types, but to protocols as well.
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
Another interesting feature of the Swift programming language when it comes to working with types, whether you've created them or not, is this concept of an extension. And what is an extension exactly? Well an extension is a way for you to be able to add new functionality to existing types. And those types could be classes or structures enumerations or with the advent of this feature into Swift 2.0 you can do it for protocols now as well. So let's see how something like this might work. So if we were to start to deal with a built in type let's say an integer type. And we want to be able to add in some sort of functionality so maybe we wanted to maybe add a computed property let's say to an integer. And that brings up an interesting point, too. There's a kind of a list of things that you can add to two types. You could add computed properties. You could add instance methods. Or even class methods or type methods. You could provide some new initializers. And you can even make a particular or a new type or class, conform to a protocol. So there's a lot of different cool things you can do with these. So the basics here would be that I want to create an extension that maybe is going to be a new computed property, when it comes to an integer. So we're going to start by doing, like we do with so many other things, we're going to specify a key word. And that key word here is extension. And then we specify the type we're looking to extend. So in this case we're going to extend the integer type. And this could be any other type, any custom type that you've built. Although in a second, I'll explain to you why I feel you should never really write extensions. For classes or types that you have created, but we'll get to that in just a second. So I'm going to create an extension on the integer type. And what I would like to do at this point is I would like to create a new property, a new computed property, on integer. So I can save var, and then we'll just call this Derek. But you could call it anything you want, it doesn't really matter as long as it makes sense for what you're trying to do. But I just want to make it a little bit obnoxious. So you can really see this at work. And so what this is going to do is it's going to return or be of type integer. And then what I want this to do is I want to actually just double the value of the integer that we're working with so we're simply going to return and within this code block here you have access to the actual instance of that type itself by specifying these self keywords. So as you can see here this is going to receive any sort of functionality that you pass to it, so you get access to self which is the actual instance of the type you're dealing with. So I can say self dot and I can do whatever I want. I get access to all these properties but all I really want to do is say self times two. So that's ultimately what I want to do. Not an overly ambitious or crazy extension here but it's gonna be interesting to see how it works. So let's go ahead and create an integer. So we'll say myInt is gonna be equal to five. Now if I come down here and say myInt, this is going to be a regular old Int, no big deal. But if I were to look at the properties, now, I now have a Derek property on this type. So I could come in here and I could say var newValue is gonna be equal to myInt.derek, which seems like a strange name here. And then I could go ahead and print out newValue. So if I were to to save and run this you'll see here that it's going to return ten. So I've just created a new computed property called Derek on to the nth type. And then go ahead and use that and you'll see I get the result that I would expect. Now as I mentioned before I would strongly urge against you creating extensions for types that you own or for classes that you've created simply because you have the source code for that. So I would say my argument would be if you wanted to create an extension it's a very powerful feature, but I would only worry about creating extensions for types that you don't have access to at least from a source code perspective. So that would mean any other types that are built into Swift or any other libraries that you're using those would be good targets for extensions. Or maybe for types that are given to you by other people that you haven't actually received the source code for or that somebody else owns. Then maybe instead of going in and messing with their source code obviously without asking them. But if they just give you a library that contains types in it then I would definitely go the extension route. But if you have access to the source code. And it's okay for you to modify it. Then I would have just added the Derek property into whatever type that I own because it's silly for me to spread out a bunch of functionality for a particular type that I already have access to. So if I need to modify a computer property or some other piece of functionality that I have extended a type to use then I'm gonna have to search around and try to find it when it should just all be contained within the definition of that particular type. So that's just my little soapbox moment. Obviously you can do whatever you want, but that would be my recommendation. Now as far as extensions are concerned I could also add an initializer if I wanted to add some sort of other custom initializers. So I could add an initializer here and maybe we'll say that this is going to be called the initialValue. And we're going to go ahead and pass in this to be an integer. And then we'll just go ahead and say that we're going to set, self equal to initialValue * 10. Once again, probably not something you would typically do. But just an interesting concept nonetheless. So what I could do is I could now initialize this to be an integer. And then you're gonna see here that I can pass in an int or I could pass in my version here which is going to pass in a ten. And now I have a my integer. And then I can, instead of doing this new value stuff, I could simply print out my integer, and go ahead and run that. And then I would get 1,000. So you see, I can now add in computer properties. I could also add in an initializer or even another method in general. So I could say I want to create a function. And I want to call this subtract5. And this is not going to take in anything and it's going to return an integer. And all we're gonna do here is we're going to return self minus five. So I can go ahead and save that. So now that I have my integer here, I will now say that myInt is gonna be equal to myInt.subtract5. Like that. And now I can save this and run it so now I should get a thousand. And then I should be subtracting five which will give me 995. So this is definitely pretty cool. Now one thing to also make note of here is that in previous versions of Swift if you wanted to add an extension method to a specific type, you had to add it to that specific type. So if you remember in a previous lesson I actually Had created a couple of types in a protocol, which will see right here. So what I've done here is, I have created a protocol. And this protocol defines a property, identifier and a function validate. And then I have two types, employee and manager, that are going to Conform to that particular protocol. Now what I would typically have to do in the past if I wanted to extend some of this functionality. Even if I wanted to extend the functionality of types that were both agreeing to some sort of protocol I would have to come in and create an extension of those types. So I would have to say something like extension employee. And, I have to put in some sort of information here. But, what I can do now is I can, actually, create an extension of a protocol type and I can provide a default implementation. And, then I can do the same thing that I've done before as I can add in some sort of functionality or a property. So, I'll just add in a function here, maybe, that's called subtract five from identifier, or something along those lines. And I don't need to pass any information in an and I'm not going to return anything. So within this particular function, I can say, I want to get access to self and I can see the properties that are exposed or the properties and the methods that are exposed by that particular protocol. And I'm going to say that I want to go in and I want to get the identifier, and I wanna set that equal to or I want to decrement it by five like this. And you're gonna see here that there's going to be a little bit of a problem here if we try to do something like this because I'm trying to modify a property of the self of the protocol that I'm trying to add some functionality to. So if I want to do that, then I have to use a special key word on this function. That's going to tell that function and tell the type that this particular function is going to make changes to self, and in order to do that, I have to mark it as mutating. So once I do that, now I should be able to build this. And now if I were to create, let's say an employee, so we say our employee's going to be equal to employee. And we're going to pass into an identifier that's going to be 100. And then I could say, my employee, I want to subtract five from the identifier. And then let's go ahead and print empoyee.identifier so let's save this and I believe I have a print statement up above so let's go ahead and comment that out. So now if I were to save this and run it. What we would expect to happen here is I would create an employee that would have an identifier of a hundred. But I've actually created an extension on my identifiable which employee conforms to. So now I get access to this new mutating function here, which is going to decrement the identifier by five and so if I print that out now I have 95 here. So that's the basics behind extensions. So once again just to review, I can create extensions on existing types. And that will allow me to add in computed properties, initializers, methods or functions subscripts and all sorts of cool things like that and once again like I said before. I recommend the use of these to be limited to types that you don't have source code access to just so that it's a little bit easier to read and easier to maintain but ultimately these extensions allow the opportunity to add functionality that may not previously exist. But allow you to add that functionality to a type that you don't necessarily have access to.