5.2 Function Parameters
Swift and its predecessor Objective C both have a unique way of handling function parameters. In this lesson, I'll help you develop an understanding of function parameters so that you can understand the different strategies that you can use. It is important to get a good understanding of this topic, because you will see lots of different patterns that Swift developers use in the wild.
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
5.2 Function Parameters
In this lesson we're gonna talk about some of the nuances of working with the parameters when you're defining and using functions. Now function parameters are somewhat interesting beings in that there's a little extra bit of functionality in them that you may or may not see in other programming languages depending on where you're coming from. So we're going to start with the process of specifying parameter names. So once again we're gonna create a very simple function. We'll call this my function which is a horrible name but for our purposes this will work just fine. And then if you recall we use the open and close parentheses here to specify our input parameters. Now in a previous class and we just simply named them very simply. We gave them a name which was maybe a string, and another parameter which was a boolean or whatever have you. And then we did something within our function. Now granted, this is a very simple function. And if I were to call this now, I would say my function. And you'll see here that it takes in an two named parameters a name and param. But actually what's going on here is a little bit more complicated than you see at first glance. Now what's actually happening in swift functions is that we're dealing with two different types or two different sets of parameters. We have external parameters and we have local parameters. Now because we're only specifying single parameter names here these are kind of functioning as both. And what I mean by external and local is that these named parameters, name and param, are accessible to me within my function. So I can refer to name, and I can refer to param. So those are local parameters. And then I can also refer to them when I'm calling my function. As you see here, name and param. So as I mentioned in the previous lesson, the first one is going to be unused, but I can pass in some string. And the second one is going to be named and I can pass in its value. And if I have a third and a fourth and a fifth, they will all continue to be named like the second one. Now as I mentioned, this is both External and local. But I can get a little bit more explicit and I can specify both an external name and an internal name. So what does that look like? Well, if I were to come back to my function definition, let's say for the first parameter internally, I want to refer to the string as name but let's just say percent of reason externally, I wanted to refer to it as something else. I wanted it to look differently, when I was specifying what I'm actually using or when I have a user using my function so we'll say external name. So we'll basically give this two names. The first name listed is the external name. And the second name listed is the internal name. So if I were to come in here, you're going to see that I don't have access to this external name, it doesn't exist. But I do have access to name, which is the local name. But then outside of my function now when I start to use my function you're going to see that that first parameter is not only specified as having a name of external name, but now since I've specified the external name explicitly, we are now required to use that in the function call, so it's a little bit of a nuance. It's a little strange if you've never seen it before but it's actually somewhat interesting. Another interesting thing that we can do here is we can specify an external name for the second one as well. So I'll say external param. And now if I do that you're going to see that this is no longer going to work anymore because it's not named correctly so I can replace param with external param. And then it's going to work. So depending on how you like to do your development or you like to have your end users do their development, this can be somewhat good and somewhat bad because you have a choice now. You have a choice of whether or not you want to make the end users explicitly state these names. Now remember, if I don't have an external name here as the first function or as the first parameter to my function, then it's not necessary for me to, or actually I can't specify, the first name of the parameters. So I would just have to pass in some data here, so we'll just pass in a string and a Boolean. So as you can see here now, because I don't have an external name, I'm not specifying a name here. But if you come from other programming languages where you typically don't use those named parameters, maybe say in C# or something like that where you can, but typically a lot of people don't. This can be a little bit confusing and maybe a little bit unwanted. So maybe I don't want to have this external name. Maybe I don't want to have this internal name. But remember if I get rid of both now, I still have to specify the first one. And that's kind of an interesting thing to get used to if you're coming from the outside world. But have no fear, there's actually a way to get around that, if you so choose. Now, in a previous lesson, we began discussing the wild card pattern, which was the underscore. And we can use that in this particular case, as well. So, if I don't want to have to specify the external name, which in this case is parameter by default for that second value. I can simply pre-pend to this the underscore, which is now gonna make this fail again and I can now delete that. So now we're getting back into this world where I'm calling a function, and I don't have to pass the names to it. So if we were to come back in here and take a look at this. You're going to see the definition here with this underscore. But if I were to come in and start to type this my function, you're gonna see that I don't have to specify either one. They're both going to be implied. When I call my function because I am not specifying an external name for my second parameter. And then ultimately I can do that for all other parameters. So it's kind of a little bit of an interesting nuance of swift and functions. Now, another very interesting topic that is very important to understand, and this is also available in other programming languages as well, is what if I want to specify some sort of a default value for my parameters. So let's say I wanted to create a simple function here called add. And it's gonna take in two parameters, an x and a y, which are both going to integers. I'm going to return an integer, so we'll keep this very simple. And then within the body I'm simply going to return x + y. So this is pretty nice. I can just come in to add, and then I could specify a couple different parameters. I could say, maybe, 0 + 0. And that's going to obviously give me zero and I could put anything in there I'm going to get out the desired output. But what if I wanted to be able to specify some sort of default functionality so the end user doesn't necessarily have to pass any data in. Well I can do that by specifying default parameters. So I could do that by coming into my function definition here and within my parameter list. I can after the declaration of the input parameters, I can append to that in equals something. So I can say equal to zero. So I could save that now so if I came down here to call my ad, we see that by doing that I'm now given two options here. So it implicitly has created an overload for my ad function. I could specify both parameters using the top or I could just specify a single parameter with the bottom, so it's going to assume that if I don't pass in one of those values, that it's going to default it to zero. And I can actually do that for both parameters, if I would like. And if I were to do that now, you're going to see I get the same thing. Where I can pass in nothing. Or I can pass in both. This also gives you a little bit of flexibility in your creation and use of functions by specifying these default values so, based on whatever you're trying to do, the end user doesn't necessarily have to pass in any values. Now the final little nuance of functions within Swift that I wanna discuss in this lesson are called variadic parameters. And a variadic parameter uses a range, and we've seen ranges in previous lessons, to accept either 0 or more values of some sort of specified type. So let's say that I wanted to create a function that was once again going to add some values together, but I didn't want to limit the end user to specify whether they only wanted to add two numbers or three numbers. What if I just wanted to accept X numbers? Some sort of array of numbers or some sort of list of numbers that I ultimately am just going to loop through and add together, and then provide some sort of output. How could I do something like that? Well, I would specify a parameter name, like I always do. So, I could say numbers. But this time, when I specify the type, I specify the type and then I give it the range indicator the dot dot dot. So what this is telling swift is that I'm going to accept any number of arbitrary inputs into this function, and then I'm going to do something with it, and they're all going to be assigned to numbers. So if I go to access numbers, you're gonna see here that it gives me an array of integers. So then I can go ahead and loop through these just like I would normally and generate a sum based on that information and go ahead and add them all together. So, I would ultimately return something here. So we'll just return zero, but you can go ahead and fill in that with a block of code that will add all those numbers together. And then the interesting thing is when I come down to add, so I can say var result is equal I can add, and as you see here, we're going to be allowed to provide some sort of arbitrary numbers of integers. So I can pass in one, I could pass in none, I could pass in several. And it's gonna continue allowing me to do this and I could just continue to put an arbitrary number of values in here as long as they're integers It will continue accepting those and build successfully. And ultimately generate the output that I would expect. So those are some of the nuances in working with the function inputs. Now in the next lesson we're gonna talk a little bit about another important aspect of functions in the world of Swift and that has to do with function types and closures.