闭包是啥?
闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。或者说是函数和其引用环境的组合体。
闭包指的是一个函数和与其相关的引用环境组合而成的实体。简单来说,闭包=函数+引用环境
。
上面的概念每句话都是精髓,理解不了?没关系,看下例子就懂了。
package main
import "fmt"
func test() {
name := "tom"
age := "18"
s := func() string {
return name + age
}
msg := s()
fmt.Printf("msg: %v\n", msg)
}
func add() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
func main() {
test()
var f = add()
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
fmt.Println("变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。")
f1 := add() //闭包的生命周期主要在重新引用
fmt.Println(f1(10))
fmt.Println(f1(20))
f = add()
fmt.Pr:ntln("----------重新引用--------")
fmt.Println(f(30))
}
看一下运行结果:
msg: tom18
10
30
60
变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。
10
30
----------重新引用--------
30
那我们先拆开来说第一个函数:
func test() {
name := "tom" //函数内部声明了两个变量
age := "18"
s := func() string { //声明一个匿名函数
return name + age //这里浅浅的引用一个闭包的概念,闭包是将函数内部和函数外部连接起来的桥梁。或者说是函数和其引用环境的组合体,说白了就是在函数里定义了一个函数,通过函数内部引用函数外部环境变量。
}
msg := s() //然后多说两句废话,匿名函数说白了就是没有函数名称的函数,调用的方法呢就两种,一个是类似于这种定义成一个变量,通过变量执行函数,另一种自执行匿名函数:在匿名函数后加调用的参数列表"()"
fmt.Printf("msg: %v\n", msg)
}
理解了第一个函数的话,再去理解第二个函数就会简单很多,这两个函数之间没有任何关联性,只是为了方便理解。
在简单的说一下闭包的概念,闭包=匿名函数+引用环境(外层代码定义的变量),即有状态的匿名函数,也可以说:如果匿名函数引用了外部变量,就形成了一个闭包.
func add() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
直接看一下main函数怎么调用的和运行结果!!!!
func main() {
test()
var f = add() //声明喽,f现在就是一个函数
fmt.Println(f(10)) //x=x+y y=10 x=0+10
fmt.Println(f(20)) //x=x+y x=10 y=20 x=10+20
fmt.Println(f(30)) //x=x+y x=30 y=30 x=30+30
fmt.Println("变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。")
f1 := add() //闭包的生命周期主要在重新引用
fmt.Println(f1(10))
fmt.Println(f1(20))
f = add()
fmt.Pr:ntln("----------重新引用--------")
fmt.Println(f(30))
}
就这么简单,下面在看两个例子,如果理解了上面的内容的话下面的两个例子也是一看就懂。
案例1:
package main
import (
"fmt"
"strings"
)
func makeSuffixfunc(suffix string) func(string) string {
return func(filename string) string {
if !strings.HasPrefix(filename, suffix) {
return filename + suffix
}
return filename
}
}
func main() {
jpgFunc := makeSuffixfunc(".jpg")
txtFunc := makeSuffixfunc(".txt")
fmt.Println(jpgFunc("test"))
fmt.Println(txtFunc("test"))
}
运行结果:
test.jpg
test.txt
案例2:
package main
import "fmt"
func calc(base int) (func(num1 int) int, func(int) int) {
add := func(num1 int) int {
base += num1
return base
}
sub := func(num1 int) int {
base -= num1
return base
}
return add, sub
}
func main() {
f1, f2 := calc(10)
fmt.Println(f1(2), f2(1))
}
运行结果:
12 11
一看就懂了吧,so easy!!!!