闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。或者说是函数和其引用环境的组合体。
闭包指的是一个函数和与其相关的引用环境组成的实体,简单来说,闭包=函数+引用环境。
代码实例1:
package main
import "fmt"
func add() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
func main() {
var f = add()
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
fmt.Println("----------")
f1 := add()
fmt.Println(f1(90))
fmt.Println(f1(79))
}
运行结果
10
30
60
----------
90
169
变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。
闭包进阶示例1:
package main
import "fmt"
func add(x int) func(int) int {
return func(y int) int {
x += y
return x
}
}
func main() {
var f = add(1)
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
fmt.Println("----------")
f1 := add(2)
fmt.Println(f1(90))
fmt.Println(f1(79))
}
运行结果
11
31
61
----------
92
171
这个实例中的x变量,会在运行中改变,且在f的生命周期中,变量x一直有效
闭包进阶示例2:
package main
import (
"fmt"
"strings"
)
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasPrefix(name, suffix) {
return name + suffix
}
return name
}
}
func main() {
jpgFunc := makeSuffixFunc(".jpg")
txtFunc := makeSuffixFunc(".txt")
fmt.Println(jpgFunc("test"))
fmt.Println(jpgFunc("test12"))
fmt.Println(jpgFunc(".jpg")) //return name
fmt.Println(txtFunc("test"))
fmt.Println(txtFunc("tests"))
}
运行结果
test.jpg
test12.jpg
.jpg
test.txt
tests.txt
变量suffix一直有效
闭包进阶实例3
package main
import "fmt"
func calc(base int) (func(int) int, func(int) int) {
add := func(i int) int {
base += i
return base
}
sub := func(i int) int {
base -= i
return base
}
return add, sub
}
func main() {
f1, f2 := calc(10)
fmt.Println(f1(1), f2(2))
fmt.Println(f1(5), f2(4))
fmt.Println(f1(2), f2(3))
}
运行结果
11 9
14 10
12 9
base都是同一个,就像引用变量一样
闭包,只要牢记闭包=函数+引用环境。