Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.6 Functions

Within any programming language, you are often going to want to reduce the number of times you have to write the same piece of code. This concept typically takes the form of functions or methods. In this regard, the Swift language is no different. In this lesson we will cover the basics of functions and function types in preparation for learning more about closures.

Related Links

2.6 Functions

One of the more important features of any programming language is the ability to take several lines of code or chunks of code and put them together, and be able to reference them with a single name and what I'm talking about here is the concept of methods or within the Swift programming language, functions. So a function is merely a way to put together a block of statements that I can then execute simply by calling by name. So let's go ahead and see how we can start to create these functions, and then call them whenever we need to. So when we're creating a function, we're going to start by using the FUNC or FUNC keyword. Then, directly following that we're going to want to specify the name of the method. Now, typically in objective c, and kind of following suit within. [BLANK_AUDIO] Swift, what we're going to do is we are going to start our method name with a lowercase letter and then every other letter that starts a word after that will be uppercase or will be capitalized. So let's start an example, let's say we are going to have a method here that says, that's called sayHello. [BLANK_AUDIO] Now at this point, we can then choose to allow the user to specify some sort of input but in this case we're gonna say there's gonna be no input into this p, method or there's gonna be no parameters into this function, and then ultimately at this point we could then have it return some value. But in this case we're not worried about that either. So here we go, here is the basic definition of a function that doesn't actually do anything. So, let's make it do something. So, in this case we're gonna have it print a greeting, so we'll just say, Hello there. Quite simple, nothing overly fancy, and then if we wanted to call this method or this function, we'd just specify it by name, we say sayHello, and there you have it. We get it printed out here, Hello there. But by itself, that's not very interesting and there's not really too much going on there. Let's say, I wanted to be able to pass some data in to do some further data processing. Well, the way that we're going to specify an input value is through the use of a parameter. So the way that we do that, if you remember in objective c, you kinda had that concept of the name of a parameter and a sem, and a colon well, that has followed over into Swift as well. So in this case, we're going to say that we're going to have an input parameter into this method whose name is going to be name, and we're gonna specify its type is going to be a String. So there we go, now we have a method that takes in one input parameter. Whose name is name and its type is string and as you can see now, I'm calling sayHello without any parameters. So this is obviously not going to work, I have to specify something within it. So here I can say, so I'm going to pass in my name to this method just like this, and now I can do something with that. So maybe I can do a print line here and I'll actually concatenate this and I'll do plus name, so now when I call it, I'm passing in Derek as this name, and then I'm concatenating that onto the str, string when I'm printing it, so that's kinda nice. I can see there's some use there, I can some pass some data in, I can pass some parameters in and have it do something. Well, what if I needed to get some data out of it? Okay. Well, then we can specify what's known as a return value. And return values are kind of interesting within Swift, in that we specify the return value at towards the end of the method signature. And when I say method signature, I'm talking about this entire first line here. So, a method signature typically consists of the name of a method, any sort of input parameters, and it's output parameters. And that's going to become very important to understand a little bit later on in this lesson, as we start to talk about the names of a method, because that's gonna fall over into another concept called closures that we're gonna talk about very soon. So when we wanna specify a return value, we, we do so with an arrow at the end of the methods signature. So we're gonna do a dash and a greater than sign, and now we can specify what the return type is going to be, and in this case, sure. We'll return a string, so now as you can see, I'm getting another error here because it notices that I said there's a return type of string, but I'm not actually returning anything. So let's do that now, instead of actually printing this out, I'm going to return this value. So, I will say var greeting is going to be equal to this value, and then I'm going to return using the return keyword greeting, so there we go. So, now we can see here that when I call sayHello passing in Derek it's actually going to pass in Derek as the name parameter. It's going to create this greeting variable, it's going to concatenate these two strings, and then it's gonna return the result, and as you can see I get back, Hello there, Derek. So that's pretty simple. But what if wanted to do multiple input variables or multiple input parameters? We can definitely do that. So let's start to specify two let's, let's say we have a greeting here, which is going to be a string, and then we separate these input parameters with a comma, so I can have basically as many in here as I would like, and I'm still gonna return a string. So, let's modify this just a little bit, so instead of calling this var greeting, since that's gonna cause a little bit of confusion there, we'll call this var return value, so instead of assuming, how I want to greet someone with their name? I'm going to pass in that particular greeting, so we'll do this. We'll concatenate greeting plus, and then we'll keep in here the comma and space and then the name, and then we'll return greeting. So now, I'm going to get an error here because I'm only passing in one parameter to this method and it's expecting two. So I can now come in here and say all right, well I wanna pass in Hello there, and Derek. And then I have to make sure, I've got the correct return value here instead of greeting I'm going to return, return value, so there you go. Now you have the returning of Hello there, and Derek. So it's kind of nice I can return, I can pass in multiple values, I can get some value out using a return value, but you're not limited to a single return value, and this is kind of an interesting concept because in a lot of other languages, they're only going to allow you a single return value, but Swift is not that way. I can specify multiples, and in order to do that, I'm going to return, instead of a single string here, I can specify something called a Toople or a tupple depending on how you refer to it. And that is merely groupings of data that's kind of held together to pass data around, it's kind of a simple data structure, but the way you declare them or define them is using open and close parentheses. So I'm gonna specify that I'm gonna have two return parameters this time. I'm going to have in here the full greeting, so we'll say full greeting, which is going to be a string, and then I'll also just return in some arbitrary number. And we'll say that this is gonna be number, and then this is gonna be integer, something like that. So nothing very sophisticated, but as you can see here it doesn't like this return value because I'm only trying to return a single value. I'm not actually returning this tuple that I have been saying, or that this method signature is defining. So the way that we're gonna do that is we're going to return a tuple in the same way that we defined it, with open and closed parentheses. And then I will return here, the return value as well as, we'll say the number 5. That's just an arbitrary number, but as you can see here now, the return value of sayHello as I pass this data in, is actually this tuple. So I can look in to here, and you're gonna see that there were two values returned to the string of Hello there, Derek as well as the integer value of 5. So now, I can pass multiple values into a function. I can get multiple values out as well, and one thing that we're gonna see quite often now as we get into more complex topics such as structures and classes and things like that. As we saw in a previous lesson we started to introduce the ideas of optionals. What happens if we're creating these functions like the two int on a string type that we saw before that returned an optional? Well how do we handle this concept of an optional? If our method doesn't actually know, if it's gonna return a valid number so let's create another function here. So let's say we wanted to do something similar to the ToInt method that was found on the string type. So let's say we wanted to create a func and it's gonna be called convertToInt. So this basically gonna be very similar to what we saw before on the string type, but just to kind of give you a visualization of how this could work. So we're gonna pass in a value, and this is going to be a string, and then we want to return this in integer form, but because we don't know if they're gonna pass in a valid integer in its string form. We know we wanna return an int, but we're not sure if it's gonna be valid or not so we specify the question mark to say that this is going to be an optional Int. So now, within our method, we can now return a value. We can say we want to return value dot twoInt, like that. So now we can start to use this. We can say, convert to Int we can pass in 5, and we'll see that the response there is sum 5 because it's an optional 5. But we can also do convert and we can put in a, and we would expect to get out nill. Right, so that's because the return type of this particular function is an optional. So definitely, something to keep in mind if you've ever been familiar with using the nullables in some other languages. Another nice feature that the Swift programming language uses when you're working with parameters and functions is that sometimes, you want to be able to default a value in that particular parameter list to be something so you don't necessarily have to specify it. So let's go ahead and see what something like that would look like. So let's say, we wanted to continue to use this example, but instead of saying we have to pass some, some value in as a string, we could say, well let's just put this in as a default of 0, which is just basically stating that we can default the value of this to be 0, should we need to or should we want to. So what this allows us to do if we use a default value is to call this particular method without passing in any data. We don't have to pass any value in because it's been defaulted to 0. But we could pass in say 5 should we want to, to actually get that out by specifying the name of that particular value that we're passing in. So that's one thing to keep in mind, that when you're using a default value you either have to not pass anything in here for that particular parameter, or you have to explicitly state it by name. Another very interesting feature of function within the Swift programming language which is definitely. Available in others as well, is this concept that they refer to as variatic parameters which means, what happens if I wanna create a function that takes in an arbitrary number of arguments. I don't want to say, I'm gonna create a bunch of different methods. One that's gonna take one integer value, one that's gonna take another integer value. So, let's take a look at an example. If I created a function, and I wanted to add some numbers. And we'll call this add, and let's say, I don't know how many values make sense to put into this. I just know that, I want to add all the values that come in. Well you could really go through the process of saying first is going to be an Int, and then we could this, and then we could obviously return first, something like this. Well, what happens if we need a method? What happens if we need a function that's going to add two numbers? Well, we'd have to do func, add, and we would do first, which is gonna be an Int, and then we're gonna have second, which is gonna be another Int, and then this is gonna return an Int. So as you can see here, this is going to become very, very laborious. You can do it if there's only going to be a few different variations of this, but it becomes to be, it becomes a lot of maintenance on your side. So what we can do is we can use this concept of a variadic parameter. So I can say func, will call this add, and now I'm going to specify that I want to pass in some numbers. Right, and we're gonna, we're gonna assume at this point that these are going to be integers for our example. So I'm gonna say that, I want these numbers to be of integer type, but there's going to be a range of them. So like you've seen before, I'm going to pass in a collection or a basically a list of numbers of, whose length is indeterminate at this point, so I can pass in when I'm calling this method, I could pass in 1, 2, 3, 4, 5, as many as I want to or need to. Now the return type of this is going to be an integer. So now I have this numbers variable that contains a collection of integers that I can then work on, and so I can create the sum of all of these integers by creating a variable total, and we will initialize this total to be equal to 0. And then we will use our four in construct, so we'll say four each num in numbers, so we're gonna loop through all of them, it doesn't really matter order. And then I'm going to say that total is going to be incremented by the next number, like that. So now, by the time we reach this far in the loop, total should contain the sum of all the numbers that have been passed in. So then I will return total. So now we have a method that we can use to add some sort of indeterminate amount of numbers. So I can come down, I can call add, and I'm gonna pass in 1, 2, 3, 4 and 5. And so the sum of all of these put together is going to be 15. And just so there's no confusion, I'm gonna get rid of these first two examples. So that's kind of nice, but now I can call add, and I could maybe just do one and two. And now we'll get 3, and I can call add again and I can say 1, 2, 3, 4, 5, 6, 7, 8, and 9, and it's going to go through and add all of them together for me as well. So now I've created one function that can handle an indeterminate amount of inputs, so that can be quite powerful, as you can probably imagine. Now the final thing that I would like to discuss, now there's a couple other things you could continue to read about as far as functions are concerned, but what's very interesting to think about when you start to use functions is that functions are really types in and of themselves, so what does that mean. Well, let's go back and take a look at a very simple example. If I have a function here, and I call this do stuff. And let's say it takes in a parameter whose name is string and it returns a string. So now it doesn't really matter, what this is actually returning, so in this case, I'll just say return Hi. So what we talked about before when we were talking about the concept of a signature. Is kind of equated in swift to a function type. So, what is a function type? The type of a function is referenced by it's inputs and it's outputs. So. if I wanted to use kind of a, shortened version of that, I could say that this particular function type is going to be string, since that's its input, and it's output is going to be string. Now you look at this and say, well what does this do? I don't understand. What's the point of this? Well, the point of this is being able to take references to functions that match this particular signature or type, and be able to pass them around as their own parameters, or as their own return values. So the way that we would do that, is we can take this particular function type, and use it as the type of a variable. So let's say I create a variable, and we'll call this stuff, which we've done before so this is the creation of a variable.e And then we're gonna specify that its type is going to be a String input and a String output. So right here, we have just created a variable called stuff that takes in a function type that matches this particular function called do stuff. And then I could even go a step further to initialize this to be equal to the method doStuff, just like this. And as you can see here after this is executed it knows that the stuff variable contains a function. All right. So we can see that there. So now anywhere that I run around and use this stuff variable. It's going to see it takes an input of a String and returns a String. So I can say stuff and I can pass him anything at this point because I am not actually doing anything with it. But it's now going to use this as a variable, but it's actually a function that I can pass data in and get something out. Now, this is a very simple example but if you wanted to create some complex logic in a function that you wanted to be able to pass around and reuse in different mechanisms,. Then you can do it this way, you can bundle up a function into a variable, and use it as an input parameter, as an output parameter, all those types of things. Now this is going to become very important, and we're gonna talk about this a little bit more in the upcoming lessons when we start to introduce the concept of closures. But until then, just keep in mind that it's possible to create functions, store them in variables based on their signatures or their function types, and then pass them around just as any other variable would do.

Back to the top