- 基本介绍
闭包就是
一个函数
和与其相关的引用环境
组合的一个整体
(实体)
案例:
package main
import (
"fmt"
)
//累加器函数 (返回的是一个匿名函数func (int) int)
func AddUpper() func(int) int {
var n int = 10
return func(x int) int {
n = n + x
return n
}
}
func main() {
f := AddUpper()
fmt.Println(f(1))
fmt.Println(f(2))
fmt.Println(f(3))
fmt.Println(AddUpper()(10))
fmt.Println(AddUpper()(20))
}
说明:
1、AddUpper
是一个函数,返回的数据类型是fun (int) int
2、闭包的说明
var n int = 10
return func(x int) int {
n = n + x
return n
}
返回的是一个匿名函数,
匿名函数
引用到函数外的n
,因此这个匿名函数和n就形成了一个整体,构成闭包。
3、这样理解:闭包是一个类,函数是操作,n是字段
函数和它使用到的n构成一个闭包
4、当我们反复的调用f函数
时,n
只会初始化一次,因些每调用一次就会累加。
5、闭包的关键就是要分析出返回的函数它使用(引用到的变量),因为函数和它引用到的变量共同构成闭包。
//累加器函数 (返回的是一个函数func (int) int)
func AddUpper() func(int) int {
var n int = 10
var str = "hello"
return func(x int) int {
n = n + x
str += string(36)
fmt.Println("str=", str)
return n
}
}
func main() {
f := AddUpper()
fmt.Println(f(1))
fmt.Println(f(2))
fmt.Println(f(3))
fmt.Println(AddUpper()(10))
fmt.Println(AddUpper()(20))
}
- 最佳实践
1、编写函数
makeSuffix(suffix string)
,可以接收一个文件后缀名(比如.jpg
),并返回一个闭包
2、调用闭包,传入一个文件名,如果没有指定后缀,则返回文件名.jpg
,如果有后缀,则返回文件名
3、全用strings.hasSuffix
函数来判断某个字符串是否有指定的后缀。
package main
import (
"fmt"
"strings"
)
//编写函数 makeSuffix(suffix string),可以接收一个文件后缀名(比如.jpg),并返回一个闭包
//调用闭包,传入一个文件名,如果没有指定后缀,则返回 文件名.jpg,如果有后缀,则返回文件名
//全用 strings.hasSuffix 函数来判断某个字符串是否有指定的后缀。
func makeSuffix(suffix string) func(string) string {
return func(name string) string {
//如果name没有后缀,则name + suffix
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
//如果有就直接 返回 name
return name
}
}
func main() {
f := makeSuffix(".jpg")
fmt.Println("文件名是:", f("cat"))
fmt.Println("文件名是:", f("bird.jpg"))
fmt.Println("文件名是:", f("mouse.avi"))
fmt.Println("文件名是:", makeSuffix(".mp3")("song.mp3.mp4"))
}
说明:
1、返回的匿名函数
引用到了 makeSuffix(suffix string)
函数的suiffix
变量,形成了一个闭包。
2、我们体会一下闭包的好处,使用传统的方式,每次都要传入一个后缀名
,(除非用全局变量
),使用闭包的好处是,可以不用全局变量
,不用反复传入后缀名.jpg
3、
网友评论