Detailed Explanation of Closures in Golang

Before explaining closures, let's take a look at anonymous functions in Golang.

Anonymous Functions¶

Anonymous functions can also be called function literals, lambda functions, or closures. The concept of closure has its roots in the mathematical evaluation of expressions in lambda calculus. Technically, there is a subtle difference between anonymous functions and closures: an anonymous function is a function without a name, while a closure is an instance of a function. To implement closures in Golang, anonymous functions are inseparable.

Let's look at an example of an ordinary function first, for example:

func add(x, y int) {
	fmt.Println(x + y)
}

The calling method is as follows:

add(1, 2) // 输出 3

Let's see how to use an anonymous function to achieve the same functionality:

func(x, y int) {
		fmt.Println(x + y)
	}(1, 2)

This anonymous function has the same function as the normal function above, the difference is

  • no name
  • Call directly after definition

Next, use an anonymous function by creating a function that returns a function. Functions generally return basic types such as integers, strings, and structures, but in Golang, a function can return another function. The following is an official Golang example:

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

The return type of this function is a function of func(int) int type. You can assign the return value of this function to a variable, and then call this variable in the same way as calling a function, for example:

pos := adder()
pos(1)

Closures

Through the above explanations, we already know the definition and usage of anonymous functions, and also understand that a function can return another function, and then explain the closure.

In Golang, a closure is a function that references a variable outside its scope. A closure can outlive the scope in which it was created, so it can access variables in that scope even after that scope is destroyed. The adder() function above returns a typical closure.

Anonymous functions in Golang are also called closures. Anonymous functions are a special type of function without a name. Closures can be considered a special type of anonymous function.

A closure in Golang consists of two parts: the function body and the context in which the function is executed. The function body defines the logic of the closure, and the context contains variables outside the function. When the closure is created, references to external variables are saved in the context, and these external variables can be accessed at any time inside the function body. Take a look at an example that slightly modifies the adder() function above:

package main

import "fmt"

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		fmt.Println("执行前 sum =", sum)
		sum += x
		return sum
	}
}

func main() {
	pos := adder()
	for i := 0; i < 4; i++ {
		fmt.Println("执行后 sum =", pos(1))
	}
}

The result of the operation is as follows:

执行前 sum = 0
执行后 sum = 1
执行前 sum = 1
执行后 sum = 2
执行前 sum = 2
执行后 sum = 3
执行前 sum = 3
执行后 sum = 4

It can be seen that the external variables referenced by the closure function are saved in the context environment (it has not been destroyed), and each time the closure is executed, the variables in the closure save the value after the last run.

summary

Closure is a feature derived from functional programming languages. Functions can either return a function or accept a function as a parameter (such functions are called higher-order functions). Golang also supports functional programming. Closures are used extensively in Golang and are often used with Goroutines and channels.

Guess you like

Origin blog.csdn.net/luduoyuan/article/details/131691852