Functions
Tags: go, codenewbie
Published: 2021-04-18 20:49:10

---
title: Functions
series: Go Fast With Go
published: true
description: An overview of using functions in Go
tags: go, codenewbie
cover_image: https://sdtimes.com/wp-content/uploads/2014/12/1212.sdt-github.jpg
---
## Function Declaration
Declaring functions in Go is very straightforward. In fact, we have already declared a function in all of our programs so far. The `main` function is required in every binary executable (a program we want to run on its own, not a library we want to share). As with loops and conditional statements, we need to follow the "one true brace style."

```go
package main

import "fmt"

func main() {
	fmt.Println("We are finally talking about functions!")
}
```

Let's go ahead and declare a more complicated function outside of main. `add` will take two integers and return an integer.

```go
package main

import "fmt"

func add(x, y int) int {
	return x + y
}

func main() {
	sum := add(2, 3)
	fmt.Println("The sum of 2 + 3 is", sum)
}
```

1. **func add**
With the keyword `func` we are telling the Go compiler `add` is a function. 

2. **(x, y int)**
In the parentheses we are declaring the names of our parameters `x` and `y`. We also need to tell the compiler what type of arguments to expect. Here we are saying the arguments should both be of type `int`. We could alternatively declare each parameter type like this: `func add(x int, y int)`. 

3. **int {**
After our list of parameters we need to declare what type of data `add` will return, in this case `int`. If we don't return anything in function we leave this part blank ex) `func printLine(msg string) {`

4. **return x + y**
In our function body we return the value of x and y added.

**NOTE:** There is no implicit return like in Ruby.

## Returning
In Go you can return multiple values!

```go
func addAndSubtract(x, y int) (sum, difference int) {
	sum = x + y
	difference = x - y
	return sum, difference
}
```

Here we are still taking two `int`s, but now we are returning their sum and their difference! Note the use of parentheses when we return more than one value (this is necessary). In this example we can also see that Go allows us to name our return values; though, it is not necessary. We could have alternatively written this: `func addAndSubtract(x, y int) (int, int)`. When we name our return values they are initialized to their zero value (we don't need to explicitly initialize them in our function body).

**NOTE:** It is important to remember that although we can always return any number of values in Go, this functionality should not be abused as it can lead to avoidable complexity.

## First Class Functions
Go functions are first class. This means you can assign them to variables, send them as arguments to other functions, and even return functions. There are also *function literals* in Go AKA anonymous functions, as well as closures. JavaScript developers should feel right at home with this functionality.

```go
package main

import "fmt"


func addNumber(number int) func(int) int {
	return func(num int) int {
		return number + num
	}
}

func main() {
	add42 := addNumber(42)
	fmt.Println(add42(10)) //prints 52
}
```

This example demonstrates how to write a function literal, return a function, assign it to a variable, and create a closure. Let's go through the code step-by-step.

1. **func addNumber(number int) func(int) int {**
We are declaring our function `addNumber` here. It will take an argument called number of type int and `addNumber` will return a function. It may seem superfluous, but we must tell the Go compiler what kind of function addNumber will return. `func(int) int` is simply the type signature for the function we are going to return. The function we are returning will take an `int` as a parameter and return an `int` value.

2. **return func(num int) int {**
This is where we are returning our anonymous function (called a function literal in Go). It will take an `int` as an argument and return an `int` value.

3. **return number + num**
We are simply returning the parent function's `number` argument added to the function literal's argument `num`. 

4. **add42 := addNumber(42)**
Here we are assigning the return value of addNumber (our function literal) and assigning it to the variable `add42`. `add42` now points to a function that will add whatever number we pass it with 42 because that was the number we passed to addNumber when we initialized `add42`. This is where the closure is created.

### Simplifying With Custom Types
In a statically typed language we need to tell our compiler what kind of data our variable should hold. Go has a number of built-in basic types such as `int`, `float`, `bool`, and `string`, but we can also declaring our own types! This will make our last example a little cleaner. Enter another reserved word: `type`!

```go
package main

import "fmt"

type addClosureFunc func(int) int

func addNumber(number int) addClosureFunc {
	return func(num int) int {
		return number + num
	}
}

func main() {
	add42 := addNumber(42)
	fmt.Println(add42(10)) //prints 52
}
```

It is extremely simple to declare a new type. You simply need a name for the type: `addClosureFunc` and the underlying implementation `func(int) int`. We can even add names to our parameter and return value if we want, just to make things a little more clear.

```go
type addClosureFunc func(sum int) (num int)
```

## Conclusion
With the power to declare functions, pass them around like any other variable, and create our own types, we can really see the power Go gives us to create very maintainable, easy-to-follow code. Next week we will talk about methods.