Welcome To Golang By Example

Function in Go (Golang)

This is the  chapter 8 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series

Next Tutorial – Constants
Previous Tutorial –All basic data types

Now let’s check out the current tutorial. Below is the table of contents for current tutorial.

Overview


A function is a group of statements that perform a specific task. In GO functions are first-order variables. They can be passed around like any other variable. 

Some point worth noting about a function name

Signature of a function

func func_name(input_parameters) return_values{
  //body
}

A function in golang

An example of a function. The below function is

func sum(a int, b int) int {
  return a + b 
}

Calling a function

A function in Go can be called in go as below

results := sum(2, 3)

Some points to note about calling a function

Function Parameters

func sum(a, b int)

Return Values

func sum_avg(a, b int) (int, int)
func sum(a, b int) (int, error)
result, err := sum(2, 3) 

Named Return Values

A go function can have named return values. With named return values , the return values did not need to be initialised in the function. The named variables are specified in the signature itself. Without named values,  only return type is specified. It is also ok to name some of the return values. For other return values only type can be specified. 

func sum(a, b int) (result int)
func sum_avg(a, b int) (sum, avg int)

Function Usages

The difference between function as type and function as values is that in type we only use the function signature whereas in function as value signature along with the body is used.  Let’s see each of this in detail so it is more clear

Generic Usage

Below is an example of the general usage of a function. We have a function sum in the below example which takes in two ints as input arguments and returns the sum.

package main

import "fmt"

func main() {
    res := sum(2, 3)
    fmt.Println(res)
}

func sum(a, b int) int {
    return a + b
}

Output:

5

Function as  Type

In go function is also a type. Two function will be of same type if

Function type is useful in 

Let’s see an example of function type in the interface. Notice that the interface shape only defines the type of function

area() int
getType() string

Code:

package main
import "fmt"
func main() {
    var shapes []shape
    s := &square{side: 2}
    shapes = append(shapes, s)
    r := &rectangle{length: 2, breath: 3}
    shapes = append(shapes, r)
    for _, shape := range shapes {
        fmt.Printf("Type: %s, Area %d\n", shape.getType(), shape.area())
    }
}
type shape interface {
    area() int
    getType() string
}
type rectangle struct {
    length int
    breath int
}
func (r *rectangle) area() int {
    return r.length * r.breath
}
func (r *rectangle) getType() string {
    return "rectangle"
}
type square struct {
    side int
}
func (s *square) area() int {
    return s.side * s.side
}
func (s *square) getType() string {
    return "square"
}

Output:

Type: square, Area 4
Type: rectangle, Area 6

Function as User Defined Type

Function as user defined type can be declared using the type keyword

package main

import "fmt"

func main() {
    areaF := getAreaFunc()
    print(3, 4, areaF)
}

type area func(int, int) int

func print(x, y int, a area) {
    fmt.Printf("Area is: %d\n", a(x, y))
}

func getAreaFunc() area {
    return func(x, y int) int {
        return x * y
    }
}

Output:

12

Function as values (or Anonymous functions)

A function in Go is a first-order variable so it can be used as a value as well. It is also called as anonymous functions because a function is not named and can be assigned to a variable and passed around.

They are generally created for short term use or for limited functionality. See the below example. In this example variable max assigned a function. Since max is created by a function that is not named, it is an anonymous function.

package main

import "fmt"

var max = func(a, b int) int {
    if a >= b {
        return a
    }
    return b
}

func main() {
    res := max(2, 3)
    fmt.Println(res)
}

Output:

3

Special Usages of Function

Function Closures

Function closures are nothing but anonymous function which can access variables declared outside the function and also retain the current value between different function calls. Let’s see an example. In below case the count value is retained between different function calls of modulus function

package main

import (
    "fmt"
)

func main() {
    modulus := getModulus()
    modulus(-1)
    modulus(2)
    modulus(-5)
}

func getModulus() func(int) int {
    count := 0
    return func(x int) int {
        count = count + 1
        fmt.Printf("modulus function called %d times\n", count)
        if x < 0 {
            x = x * -1
        }
        return x
    }
}

Output:

modulus function called 1 times
modulus function called 2 times
modulus function called 3 times

Higher Order Function

Higher-order functions are those functions that either accept a function as a type or return function. Since the function is the first-order variable in Golang they can be passed around and also returned from some function and assigned to a variable. In below example

package main

import "fmt"

func main() {
    areaF := getAreaFunc()
    print(3, 4, areaF)
}

func print(x, y int, area func(int, int) int) {
    fmt.Printf("Area is: %d\n", area(x, y))
}

func getAreaFunc() func(int, int) int {
    return func(x, y int) int {
        return x * y
    }
}

Output:

12

IIF or Immediately Invoked Function

IIF or Immediately Invoked Function are those function which can be defined and executed at the same time.

package main

import "fmt"

func main() {
    squareOf2 := func() int {
        return 2 * 2
    }()
    fmt.Println(squareOf2)
}

Output:

4

Use Cases of IIF functions

Variadic Function

In Go, a function that can accept a dynamic number of arguments is called a Variadic function. Below is the syntax for variadic function. Three dots are used as a prefix before type.

func add(numbers ...int)

Code:

package main

import "fmt"

func main() {
    fmt.Println(add(1, 2))
    fmt.Println(add(1, 2, 3))
    fmt.Println(add(1, 2, 3, 4))
}

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

Output:

3
6
10

Methods

Method has a receiver argument. When you attach a function to a type, then that function becomes a method for that type. A receiver can be a struct or any other type. The method will have access to the properties of the receiver and can call the receiver's other methods.

Function:

func some_func_name(arguments) return_values

Method:

func (receiver receiver_type) some_func_name(arguments) return_values

This is the only difference between function and method, but due to it they differ in terms of functionality they offer

Conclusion

This is all about function in golang. Hope you have liked this article. Please share feedback or mistakes/improvements in comments.

Next Tutorial – Constants
Previous Tutorial –All basic data types