DEV Community

Cover image for Go - (8) Advanced Functions
Chathumi Kumarapeli
Chathumi Kumarapeli

Posted on

Go - (8) Advanced Functions

Higher Order Functions (HOF)

We can pass functions as data to another function.

A function that takes in another function as a parameter or returns another function is called a Higher-order function.

func aggregate(a, b, c int, arithmetic func(int, int) int) int {
    return arithmetic(arithmetic(a, b), c)
}
Enter fullscreen mode Exit fullscreen mode

The aggregate () function takes four parameters. As you can see, the last one is another function. And the aggregate () function calls the passed-in function twice and returns an int.

First Class Function (FCF)

  • A function that is treated like another variable.

HOFs and FCFs are usually used as,

  • HTTP API handlers
  • pub/sub handlers
  • onclick handlers

Currying

  • Writing a function that takes function/s as parameters and returns a new function.
  • It is not very commonly used in programming.
// Takes two integers and returns their product
func multiply(x, y int) int {
    return x * y
}

func doMath(mathFunc func(int, int) int) func (int) int {
    return func(x int) int {
        return mathFunc(x, x)
    }
}

func main() {
    squareFunc := doMath(multiply) // Pass the multiply function to doMath
    fmt.Print(squareFunc(5))
}
Enter fullscreen mode Exit fullscreen mode

In the above example, square(5) internally does doMath(multiply(5, 5)). So the final answer is 25. Here we have wrapped multiply inside a new function that always multiplies a number by itself.

Defer

  • A keyword unique to Go.
  • Allow a function to execute automatically right before its enclosing function returns.

Why is this defer() required? Check the example below. The copyFile function has several return statements. When you open a file, you should close it once its usage is done. But you have done it before every return statement. This is tedious. So instead, you can use a defer.

func copyFile(desination, source string) (written int64, err error) {
    src, err := os.Open(source) // open file
    if err != nil { return }

    defer src.Close()

    dest, err := os.Create(desination) // create file
    if err != nil { return }

    defer dest.Close()

    return io.Copy(dest, src) // copy source file content to dest file
}
Enter fullscreen mode Exit fullscreen mode

Closures

  • Functions that reference variables that are outside their function bodies.
  • They may also access and assign to the referenced variables.
// closure function
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    c := counter()

    fmt.Println(c()) // 1
    fmt.Println(c()) // 2
    fmt.Println(c()) // 3

    d := counter()   // new counter
    fmt.Println(d()) // 1
}
Enter fullscreen mode Exit fullscreen mode

In the above example, the count variable in counter() is outside of the function body of its return function. But whenever you call c (in the main function) again and again, the reference to the count is increased.

Anonymous functions

  • Functions with no names
  • used in closures or when you return a function as a return value.

Check the example below.

func main() {
    // Anonymous function assigned to a variable
    greet := func(name string) string {
        return "Hello, " + name
    }

    // Call the anonymous function
    message := greet("Edward Cullen")
    fmt.Println(message)
}
Enter fullscreen mode Exit fullscreen mode

The above example will print Hello, Edward Cullen


Top comments (0)