闭包:引用了外部变量的匿名函数。
公式:函数 + 引用外部变量 = 闭包

闭包在引用外部变量后,闭包中可以修改变量,变量会随着闭包的生命周期一直存在。

闭包的作用:

缩小变量的作用域,减少对全局变量的污染,下面的累加器如果用全局变量实现,全局变量容易被他人污染,而且要实现n个累加器就需要n个全局变量。而使用闭包,可通过accumulator1, accumulator2 := Add(1) …
使用闭包实现一个id唯一的累加器:

package main

import (
	"fmt"
	"sync"
	"time"
)

var lock sync.RWMutex

func Add(value int) func() int  {
	// 返回一个闭包
	return func() int {
		// 上锁
		lock.Lock()
		defer lock.Unlock()
		// 累加
		value++
		// 返回累加值
		return value
	}
}

func main() {
	accumulator := Add(1)
	for i:=0;i<10;i++ {
		go func() {
			fmt.Println(accumulator())
		}()
	}
	time.Sleep(5*time.Second)
}

运行结果:
在这里插入图片描述

注意:

package main

import "fmt"

func print() []func() {
	b := make([]func(), 3)
	for i := 0; i < 3; i++ {
		b[i] = func() {
			fmt.Println(i)
		}
	}
	return b
}

func main() {
	f := print()
	f[0]()
	f[1]()
	f[2]()
}

运行结果:
在这里插入图片描述
闭包引用变量i,而i最后都变成了3
改为:

func print() []func() {
	b := make([]func(), 3)
	for i := 0; i < 3; i++ {
		b[i] = func(j int) func() {
			return func() {
				fmt.Println(j)
			}
		}(i)
	}
	return b
}

运行结果:
在这里插入图片描述
使用变量j将每次i的值记录下来