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) } 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)) } 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 } 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 } 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) } The above example will print Hello, Edward Cullen

Apr 27, 2025 - 05:25
 0
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)
}

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))
}

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
}

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
}

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)
}

The above example will print Hello, Edward Cullen