Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

2.3 Functions

As software developers, one of our biggest pet peeves is having to repeat ourselves. In code, repeating yourself is a very bad habit that makes your code harder to read, fix, and modify. Functions are one of the best ways to reduce this duplication, and Go has you covered. In this lesson, you’ll learn how functions in Go are first-class citizens, meaning that they can be used as types, stored in variables, and passed around as arguments or return types as well.

Related Links

2.3 Functions

Now it's time for us to dig into one of my favorite aspects of the Go Programming language and that's functions. And functions in the world of Go are treated as first class citizens. And by that I mean they are types in and of themselves, so we can create function types, which I'll show you in a few moments, and pass them around just as you would any other variable. But generally speaking, functions in Go, just like many other programming languages, are a way to encapsulate a block of functionality that we can call from different areas within our program. And not have to rewrite this code in duplicate places and introduce a bunch of different errors, or at least the possibility of errors within our application by doing a lot of copying and pasting. So let's start off with working with a very basic function, very similarly to this main here. But we're gonna pick this apart a little bit so that it makes a little bit more sense. So let's start by creating a function, we're gonna call this one, actually, we're gonna call this zero. And the reason I'm gonna call it zero is because it's gonna take in no arguments just like our main function and it's not gonna return a value. Meaning it's just gonna do something. It's not gonna take anything in, no arguments. It's not gonna return anything out. In this case, it's simply going to do a print line and it's gonna print, well, zero. And that's it. So let's save that. And let's go ahead and forget about this print line here for the moment, and we're simply going to execute our zero function. And the way that we do that is we specify the name of that function and then we give open and close parentheses. And then if we were going to be doing any sort of passing in arguments, doing anything with that data, we would put something within those parentheses. But in this case we don't need to because, well, we're not passing anything in. So let's go ahead and run this. So we'll say go run functions.go and you're gonna see it returns a 0. So that's pretty much what we would normally expect, and that's not really too much different from half a dozen or maybe every single other programming language out there. Not that every other programming language, but pretty close. So let's start to add a little bit more interesting things or maybe some complexity to this. So we're gonna say, I wanna create another function, we're gonna call this one. And it's going to take in one argument, and it's gonna return something. So the way that we do this is just like when we're creating constants or variables, we're going to give our parameter here, our argument, a name. And we're gonna call it name, but you can call it anything you want. Any sort of valid variable name will work here. And then we need to specify the type. In this case, it's gonna be of type string. So we're gonna pass in one variable and it's going to be a string called name, and then we're gonna return a value. So the return value for Go functions is provided after the arguments outside the parentheses but before the curly brackets, which are going to specify the body of the function. So in this case I want to simply return a value. And I use the return keyword, just like many other programming languages out there. And this time I want to do a little concatenation of a string. So I'm gonna say, Hello, and I'm gonna concatenate using the plus sign, and I'm gonna say, Hello, name. And then I'm gonna end it with an exclamation point. So let's go ahead and save that. So now we get a return value so I can create a variable here. So I'll say var greeting is gonna be equal to one and I have to specify a name so I'll just say Derek. And now I can do another format.println and I'm gonna print the result of my greeting. So let's save that, and we'll once again execute our function and we get Hello, Derek. So obviously I could pass in any sort of name as an argument into my function and it will work. So this is a very basic example, but we could do multiple inputs. So I could say function two is going to be, say, firstName, which is gonna be a string and then I can do a comma separated list here. We'll say last name is gonna be a string, and then once again we'll simply return string value. So in this case I can once again do a little bit of string concatenation if I wanted to. I could say return, My name is and then I'll say, plus firstName. And then a space plus lastName. And just end there. So I can save this now. And now I can change this to be two. I'm calling function two, and I'm gonna pass in Derek and Jensen. So we can save that and then I will once again execute my application and you should see my name is Derek Jensen. So that's kind of nice, but once again we're not seeing anything different within the Go programming language than we would in many other languages. So let's flip things up a little bit here and really introduce some cool features that are in Go that aren't in a lot of other languages. So we're going to create a function here. We're gonna call this swap, and this is going to take in two values, an a which is gonna be a string and b, which is gonna be a string. And in this case I want to return something, but I wanna return multiple values. I want to return the result of me swapping the values of a and b. So how do I do that? Well, Go allows us to actually have multiple return values, and the way that we do that is where we would specify the return value of the function. We give open and close parentheses, and then we can specify the types of those return values. So we'll say string and string. So now I can return multiple values and this will really change the way you start to think about functions and how you can do logic to do certain operations within the Go programming language. So in a lot of other languages this would necessitate you to create multiple variables. Save one value into the variable, and then another one into the other value, and then swap them that way, and then return the results. But since I can return multiple values, why don't I just return b,a? And I'll show you how to use this in a second. But one interesting thing that I wanna specify at this point, too, as you can see in my swap function and in two, I have multiple inputs of the same type. So these arguments are of the same type. One optimization that Go allows you to do, when you run into these types of scenarios, is not to be as long-winded and use such a longhand notation to say, I wanna create multiple arguments of the same type. I can actually skip the first type or the first n number of types as long as the last one that is the same contains the type of which that argument is going to be. And Go is smart enough to figure it out to say, all right, well the last type that has, or the last argument that has a type here is a string. I'm going to make the assumption that all the previously defined arguments are going to be the same type as well, and you'll see that it's gonna work the same way. So if I save this and I rerun this, you're gonna see that I'm going to run my name is Derek Jensen, here. But I didn't have to specify the type for all of the inputs. So now let's go ahead and use my swap function. And I want to swap two values, a and b. So let's say var a = "Derek" and var b = "Jensen". And at this point, I want to use my swap function. So I'm going to assign these variables a and b using that inline notation that I showed you before for creating variables and initializing them. And you can also do this to assign them, so I'm gonna say a,b is gonna be equal to the result of swapping a and b like this. So let's save that. And it's arguing and yelling at me because I'm not doing anything with a and b. So let's copy these two lines and lets paste them, a and b. So let's save, so, now I specify them in the order of first name, last name, so Derek and Jensen. But if I were to run this now, you're gonna see I'm gonna get them backwards, Jensen and Derek. So being able to return multiple values may seem just like a novelty. But really, you can start to rethink the way that you do logic in functions in the world of Go, because now I don't have to create extra variables, I can just return things in a different order, and it's kind of an interesting thing. It allows you to do things in a very different way. So similarly to how we're doing this swap and returning two types, you can also do another operation which will allow you to return multiple values using named values. So we can create another function, we'll call this cool. And it's gonna take in two values again. This is gonna be an a and a b, and they're gonna be both integers this time. And then we're gonna return two values. And I can do the return list very similar to the argument list by giving them names and then specifying the type after the last one. So we're gonna call one sum, we're gonna call one difference, and they're both gonna be integers. And you can probably see where I'm going with this, so I'm gonna pass in two values, an a and a b. I'm gonna calculate the sum, I'm gonna calculate the difference and then I want to return them. But how do you do this in the world of Go with these names and what have you? Well, by the fact that I have specified names in this return list and the list, this is basically considered the variable declaration here. So I don't have to declare sum and difference. That's already been done for me. So I can simply assign to them. I can say sum is gonna be equal to a + b, and difference is gonna be equal a- b. And then how do I return these values? Well, when you do these named output variables like this, these named output arguments, I can use what's known as a naked return. And I simply use the return keyword and I don't have to specify anything and Go is smart enough to say, okay, I see that you assigned values to your named output, sum, and difference. All you have to do is use the return and everything will be fine. So let's get rid of some of this excess stuff, cuz I don't need it all anymore. And let's simply call cool. We're gonna call cool, and we're gonna pass in something simple. Let's say 10 and 7, and so what I would expect would be to get multiple results. I would expect to get 17 for the sum and then 3 for the difference. So let's go ahead and run this, and there you go. I get two values returned, 17 and 3. So that's another cool thing that you can do with multiple return values. So the last thing that I want to show you is one of my favorite parts about Go. Is that I can use these functions, as I mentioned before, as first class citizens as really types in and of themselves. So I'm gonna create a function here, I'm gonna call this execute. Now this is a little bit of a contrived example, but you'll see where I'm going here in a minute. So I wanna pass an argument into this execute function which is actually going to be a function. So I'm gonna give it a name just like I normally would, we'll call it fn. And then we have to specify the type, and the type is actually gonna be a function definition, which is going to comprise of the inputs and outputs that would be expected from a function. You just don't have to specify a name. So in this case let's keep it pretty simple, and let's say it's not gonna take in any inputs and it's gonna return an integer. So it's gonna be fairly simple here, and all I wanna do in the body here is I wanna print the result of function. So I'm simply going to do a fmt.Println, and I want to print the results of the execution of the function function, the fn function, that's it. So let's go ahead and save that. So how do I actually pass a function into a function? Well, I can create a variable in this case, and we're gonna call this myFunc. And we'll use the shorthand type inference, and we're gonna specify an inline function here. So I can create a function, and I can do this inline. And once again, because I'm doing this inline, I don't have to specify a name. So in this case, all I wanna do is I wanna specify that this is going to take no inputs. It's gonna return an integer and just as an example let's return 23, some arbitrary number. So now I've created this myFunc, and as you can see, it's complaining at me because I haven't done anything with it. So let's do something with it. I want to call my execute function and I want to pass myFunc into it. So I'm passing myFunc, which is a variable of type function that takes in no arguments or returns an integer and ultimately has a body here, returns 23. And I'm passing this pointer to this function to my execute function, which is ultimately going to print its results. So let's save that. And let's go ahead and run this, and you're gonna see that it outputs 23. So this kind of allows you some flexibility to maybe create some functions that have a body that do some sort of functionality, but maybe you have different functionality within these different functions. One that maybe does some operation on some numbers, another one that does other operations and you can create this parent function like execute here. Which is simply going to combine some input with these functions, and you can swap in and out the body, the logic within these functions, and not have to rewrite a bunch of code. You can just pass in different functions, which I think is a pretty cool feature of the language. So that is a basic introduction into the world of functions when it comes to the Go programming language.

Back to the top