参考博客:
隔离数据使用这种方式可以隔离不想让调用者的数据,输出指定的结果;或者我们想要计算函数调用的次数。
函数计数器:
// 函数计数器
func counter(f func()) func() int {
n := 0
return func() int {
f()
n += 1
return n
}
}
// 测试的调用函数
func foo() {
fmt.Println("call foo")
}
func main() {
cnt := counter(foo)
cnt()
cnt()
cnt()
fmt.Println(cnt())
}
/*
输出结果:
call foo
call foo
call foo
call foo
4
*/
countercntcounter
斐波那契数列:
func makeFibGen() func() int {
f1 := 0
f2 := 1
return func() int {
f2, f1 = f1+f2, f2
return f1
}
}
func main() {
gen := makeFibGen()
for i := 0; i < 10; i++ {
fmt.Println(gen())
}
}
/*
输出结果:
1
1
2
3
5
8
13
21
34
55
*/
makeFibGen()i
装饰函数和创建中间件
函数是Go语言的一等公民,可以作为函数的参数进行传递。装饰器和中间件指的就是函数作为参数进行传递的情况。
func wrapping(f func() string) {
fmt.Println("do my work...")
fmt.Println("wrapping function: ", f())
fmt.Println("my work finished !")
}
func sayHello() string {
return "Hello !"
}
func sayByeBye() string {
return "Bye Bye !"
}
func main() {
wrapping(sayHello)
wrapping(sayByeBye)
}
/*
输出:
do my work...
wrapping function: Hello !
my work finished !
do my work...
wrapping function: Bye Bye !
my work finished !
*/
一个函数可以根据传递进来的不同的函数产生不同的反应,传递进来的函数本质上是一个闭包。
Defer Work这一个过程主要是与Javascript的回调函数进行对比,比如在JS中:
doWork1(a, b, function(result) {
doWork2(result, function(result) {
doWork3(result, function(result) {
// use the final result here
});
});
});
console.log("hi!");
doWork1doWork2doWork2doWork3doWork1doWork2doWork3
而在Go语言,直接使用闭包进行解决:
go func() {
result := doWork1(a, b)
result = doWork2(result)
result = doWork3(result)
// Use the final result
}()
fmt.Println("hi!")
闭包可以很好保存程序运行的状态,而且让程序的逻辑更加清晰。