Functions in Golang

GolangGolangBeginner
Practice Now

Introduction

As projects grow in complexity, it is common to divide the code into multiple functions. This approach improves code readability, facilitates collaboration, and allows you to quickly reuse logic without duplicating code. In this lab, you will learn the fundamentals of creating and using functions in Go. You will see how to define your own functions, understand how Go handles parameters and return values, and learn about init functions and variadic parameters.

Key Topics:

  • Understanding what functions are and how they work
  • Declaring functions in Go
  • Passing parameters by value and by reference
  • Returning multiple values from a function
  • Using the init function to set up your environment
  • Working with variadic parameters for flexible input handling

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("`Golang`")) -.-> go/BasicsGroup(["`Basics`"]) go(("`Golang`")) -.-> go/FunctionsandControlFlowGroup(["`Functions and Control Flow`"]) go(("`Golang`")) -.-> go/ErrorHandlingGroup(["`Error Handling`"]) go/BasicsGroup -.-> go/values("`Values`") go/BasicsGroup -.-> go/variables("`Variables`") go/FunctionsandControlFlowGroup -.-> go/for("`For`") go/FunctionsandControlFlowGroup -.-> go/if_else("`If Else`") go/FunctionsandControlFlowGroup -.-> go/functions("`Functions`") go/ErrorHandlingGroup -.-> go/errors("`Errors`") subgraph Lab Skills go/values -.-> lab-149098{{"`Functions in Golang`"}} go/variables -.-> lab-149098{{"`Functions in Golang`"}} go/for -.-> lab-149098{{"`Functions in Golang`"}} go/if_else -.-> lab-149098{{"`Functions in Golang`"}} go/functions -.-> lab-149098{{"`Functions in Golang`"}} go/errors -.-> lab-149098{{"`Functions in Golang`"}} end

Creating and Running a Basic Program

First, navigate to your project directory and create a Go file:

cd ~/project
touch func.go

Use a text editor such to open func.go and add the following code:

package main

import "fmt"

func main() {
    a1, b1 := 12, 4
    a2, b2 := 12, 0

    // For the first pair
    if b1 == 0 {
        fmt.Println("The divisor cannot be 0")
    } else {
        fmt.Println(a1 / b1)
    }

    // For the second pair
    if b2 == 0 {
        fmt.Println("The divisor cannot be 0")
    } else {
        fmt.Println(a2 / b2)
    }
}

This code attempts two division operations and checks for a zero divisor before division. If the divisor is zero, it prints an error message.

Run the program:

go run func.go

You should see:

3
The divisor cannot be 0

Function Declaration

In the previous labs, regardless of whether the program was simple or complex, we only used the main function for operations.

A program can only have one main function, which is the entry point of the program. When we run the program, other functions are called and executed directly or indirectly within the main function.

Now let's take a look at the syntax of functions:

func functionName(parameters...)(returnValues...){
    code block
}

Here, the function name is used to identify the function. The following rules apply to the function name:

  • It can consist of letters, numbers, and underscores. However, the first letter of the function name cannot be a number. For example, func 3ab(){} is not valid.
  • When the first letter is uppercase, it can be referenced by code in external packages. When the first letter is lowercase, it can only be used within the package. This is similar to public and private functions.

The parameter list declares the number and type of parameters passed into the function:

  • The parameter list can be empty or contain multiple parameters.

  • Each parameter consists of a parameter name and a parameter type. For example, in the parameter list below, we declare two variables of the int type.

    func test(a, b int) (res int){}

The return value list is used to return the values needed after the function is executed:

  • The return value list is similar to the parameter list. The number of parameters can be any value.

  • Generally, the return list consists of variable names and variable types, and the variable name is optional.

  • If only one variable is returned and only the variable type is declared, the parentheses can be omitted. For example:

    func test(a int, b string) int{}

When the parameter types are the same, we can use the short writing mode. The two functions below have the same functionality:

func test(a, b int, c, d string)(res1, res2 int, res3 string){}

// Short writing mode
func test(a, b int, c, d string)(res1, res2 int, res3 string){}

Replace the contents of func.go with the following code:

package main

import "fmt"

func check(divisor int) bool {
    if divisor == 0 {
        fmt.Println("The divisor cannot be 0")
        return false
    }
    return true
}

func main() {
    a1, b1 := 12, 4
    a2, b2 := 12, 0

    // Use the check function before division
    if check(b1) {
        fmt.Println(a1 / b1)
    }
    if check(b2) {
        fmt.Println(a2 / b2)
    }
}

Run the program again:

go run func.go

You should see the same output:

3
The divisor cannot be 0

This time, the check logic is encapsulated in the check function, making the code cleaner and more reusable.

Using the init Function

Go supports an init function that runs before main. This is often used for setting up environment conditions or initializing variables before the main execution.

Replace the contents of func.go with:

package main

import "fmt"

func init() {
    fmt.Println("init statement")
}

func main() {
    fmt.Println("main statement")
}

Run the program:

go run func.go

You should see:

init statement
main statement

In Go, the init function has the following characteristics:

  • It does not have any input parameters or return values.
  • It cannot be called by other functions.

There can be multiple init functions in the same code file or the same package. The execution order is as follows:

  • The init function that appears earlier in the same code file will be executed earlier.
  • Files that have earlier alphabetical order in the same package will be executed earlier. For example, if the same package contains the following files with init functions:
a1.go
a2.go
b1.go

The execution order will be a1.go, a2.go, b1.go, because a > b and 1 < 2.

Returning Multiple Values from a Function

Go allows functions to return multiple values. This is useful for performing several related computations at once.

Replace the contents of func.go with:

package main

import "fmt"

func cal(a, b int) (int, int, int, int) {
    return a + b, a - b, a * b, a % b
}

func main() {
    add, sub, mul, rem := cal(90, 12)
    fmt.Println(add, sub, mul, rem)
}

Run the program:

go run func.go

You should see:

102 78 1080 6

Here, cal returns four values at once, illustrating how multiple return values can simplify certain tasks.

Working with Variadic Parameters

Variadic parameters allow a function to accept a variable number of arguments. This can simplify scenarios where the input size is not fixed.

Replace the contents of func.go with:

package main

import "fmt"

func printX(values ...string) {
    for _, v := range values {
        fmt.Println(v)
    }
}

func main() {
    printX("labex", "labs", "courses")
}

Run the program:

go run func.go

You should see:

labex
labs
courses

The printX function can handle any number of string arguments, making it flexible and easy to use.

Summary

In this lab, you learned how to define and use functions in Go, including how to return multiple values and accept a variable number of parameters. You also saw how the init function runs before main. By structuring code into functions, you can make your programs easier to understand, maintain, and reuse.

These skills are fundamental for building modular, scalable Go applications. As your projects grow, leveraging functions to organize code and logic will become increasingly important.

Other Golang Tutorials you may like