# Functions in Go - Organise your Code Like a Pro

Welcome back to the “Go Deep with Golang“ series!

In this blog post, we will dive into the concept of Functions in Go, a powerful feature that significantly enhances code reusability and efficiency. Functions in Go allow developers to encapsulate a set of instructions or logic that can be executed whenever needed, without having to rewrite the same code multiple times. This not only makes the codebase cleaner and more organized but also reduces the chances of errors and inconsistencies. We will explore how to define functions, pass parameters, return values, and even how to work with anonymous functions and closures. By the end of this post, you will have a comprehensive understanding of how to effectively utilize functions in your Go programming projects to create more modular and maintainable code.

Functions help you break code into reusable blocks, making your program modular, readable, and maintainable.  
Go also treats functions as first-class citizens, giving you flexibility in how you pass and use them.

Let’s explore everything you need to know about functions in Go.Basic Function Definition

Syntax

```go
func functionName(parameters) returnType {
    // function body
    return value
}
```

Example

```go
package main
import "fmt"
func add(a int, b int) int {
    return a+b
}
func main() {
    result := add(5,3)
    fmt.Println("Sum:",result)
}

// Output
// Sum: 8
```

## Function Parameters

Multiple Parameters of Same Type

```go
func greet(firstName, lastName string) string {
    return "Hello " + firstName + " " + lastName
}
```

Multiple Parameters of Different Types

```go
func info(name string, age int) string {
    return fmt.Sprintf("%s is %d years old",name,age)
}
```

## Return Value

Single Return Value

```go
func square(x int) int {
    return x * x
}
```

Multiple Return Values

```go
func divide(a,b int) (int, int) {
    quotient := a/b
    remainder := a % b
    return quotient, remainder
}

func main() {
    q, r := divide(10,3)
    fmt.Println("Quotient:",q,"Remainder:",r)
}
```

## Named Return Values

You can name return variables directly in the function signature

```go
func addAddSubtract(a,b int) (sum int, diff int) {
    sum = a + b
    diff = a - b
    return
}
func main() {
    s,d := addAndSubract(10,5)
    fmt.Println(s,d) // 15 5
}
```

In the example above, we have given names to the return values when declaring the function. This means that in the function body, we only need to assign data to those variables. At the end of the function, they are automatically returned. In the example, we declared two return variables, `sum` and `diff`, and assigned values to them within the function body. As a result, when the function is executed, we get the values of `sum` and `diff`.

## Variadic Functions

Functions can accept any number of arguments using `. . .`

```go
func sumAll(numbers ...int) int {
    sum := 0
    for _,num := range numbers {
        sum += num
    }
    return sum
}

func main() {
    total := sumAll(1,2,3,4)
    fmt.Println("Total:",total)
}
```

In the example above, we used `...int`, which is a variadic parameter. This allows the function to accept zero or more arguments of type `int`. Inside the function, `numbers` is treated as a slice of integers (`[]int`).

## Anonymous Functions

```go
func() {
    fmt.Println("I am anonymous")
}() // immediately invoked
```

or assigned to a variable

```go
greet := func(name string) {
    fmt.Println("Hello", name)
}
greet("Rohit")
```

## Functions as First-Class Citizens

You can pass functions as arguments to other functions

```go
func compute(a, b int,operation func (int,int) int) int {
    return operation(a,b)
}
func add(x,y int) int {
    return x + y
}

func main() {
    return := compute(5,3,add)
    fmt.Println(result) // 8
}
```

## Defer in Functions

defer is a keyword in go which schedules a function call after the surrounding function finishes

```go
func main() {
    defer fmt.println("This runs last")
    fmt.Println("This runs first")
}

//output 
// This runs first 
// This runs last
```

This is useful for cleanup tasks like closing files or releasing resources.

## Higher-Order Functions

Functions that return another function.

```go
func multiplier(x int) func(int) int {
    return func(y int) int {
        return x * y
    }
}
func main() {
    double := multiplier(2)
    fmt.Println(double(5)) // 10
}
```

## Closure in Go

Closure is a function that captures variables from its surroundings scope.

```go
function counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    c := counter()
    fmt.Println(c()) //1
    fmt.Println(c()) //2
}
```

This will used a lot in Go for maintaining state within functions.

## Init Function

A special function that runs automatically when a package is initialized. It run before the main() function. Making it ideal for performing setup tasks, such as configuring variables, establishing database connections, or registering services.

```go
func init() {
    fmt.Println("This runs before main()")
}
```

### Key characteristics of init()

* No arguments or return values
    
* Automatic execution
    
* Multiple `init()`
    
* Guaranteed order of execution
    
    * Packages: The `init()` functions of imported packages are executed before the `init()` functions of the main package
        
    * Wishing a package: Go initialises variables and constants first, and then runs the `init()` functions. If there are multiple `init()` functions, they are executed in the order they appear in the source file. if spread across multiple files, they are run in alphabetical order of the filenames.
        

## Conclusion

Functions in Go are the backbone of clean, modular programming.  
With the flexibility to return multiple values, accept variable arguments, and even be passed as parameters, functions make Go both simple and powerful.

Once you master functions, you can start building more organized, reusable, and maintainable programs.
