闭包介绍
基本介绍:闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)
闭包本质上返回的是一个函数,但是函数会用到函数外面的一些变量,然后他们组成了一个共同的整体,这个整体我们称之为闭包。
func AddUpper() func(int) int {var n int = 10return func(i int) int {n += ireturn n}
}func main() {f := AddUpper()fmt.Println(reflect.TypeOf(f))fmt.Println(f(1))fmt.Println(f(2))fmt.Println(f(3))
}func(int) int
11
13
16
1)AddUpper 是一个函数,返回的数据类型是 fun(int)int
2)闭包的说明
这块代码形成闭包,返回的是匿名函数,但是这个匿名函数引用到函数外的n,因此这个匿名函数就和n形成一个整体,构成了闭包。
var n int = 10return func(i int) int {n += ireturn n}
3)可以这样理解:闭包是类,函数是操作,n是字段。函数和它使用到n构成闭包。
4)当我们反复的调用f函数时,因为n是初始化一次,因此每调用一次就进行累计。
5)要搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。
闭包的本质就是返回的函数和引用的类型构成了整体,它引用到的这个变量不会每次初始化,而是不断的累加,也就是每次变量都是会发生变化的。
闭包
闭包的最佳实践
请编写一个程序,具体要求如下:
1)编写一个函数 makeSuffix(suffix string)可以接收一个文件后缀名(比如.jpg),并返
回一个闭包。
2)调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg),则返
回文件名.jpg,如果已经有.jpg后缀,则返回原文件名。
3)要求使用闭包的方式完成
4)strings.HasSuffix 该函数可以判断某个字符串是否有指定的后缀
package mainimport ("fmt""strings"
)func makeSuffix(suffix string) func(string) string {return func(filename string) string {if strings.HasSuffix(filename, suffix) == true {return filename}return filename + suffix}
}func main() {a := makeSuffix(".jpg")f := a("test")fmt.Println(f)
}
里面的函数 return func(filename string) string使用到外面的函数makeSuffix变量,这个变量是函数外面的一个变量,因此这个返回的匿名函数和外面的suffix构成了一个闭包,外面函数的变量只需要传入一次,然后返回的函数可以无限使用外面的变量值。
代码说明:
1)返回的屋名函数和 makeSuffix(suffix string)的 suffix变量 组合成一个闭包,因为 返回的函数引用到suffix这个变量
2) 我们体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入后缀名,比如.jpg,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把!(最大的好处就是将匿名函数引用到的变量保留下来,在下一次调用的时候接着使用,函数是不行的,调用一次它的栈就销毁了,它原先的变量就没有了,除非你有全局变量,但是闭包不使用全局变量也可以搞定这件事)