其实 Go 语言的赋值和函数传参规则很简单,除了闭包函数以引用的方式对外部变量访问之外,其它赋值和函数传参数都是以传值的方式处理 -- go语言高级编程
闭包函数:返回值是一个函数 golang闭包函数的记忆功能
package main
import (
"fmt"
)
// Accumulate 提供一个值, 每次调用函数会指定对值进行累加
func Accumulate() func() int {
var value int
fmt.Println("value的地址 outer", &value)
// 返回一个闭包
return func() int {
// 累加
value++
fmt.Println("value的地址 inner", &value)
// 返回一个累加值
return value
}
}
func main() {
// 创建一个累加器, 初始值为1
accumulator := Accumulate()
// 累加1并打印
fmt.Println(accumulator())
fmt.Println(accumulator())
}
执行结果:
- value的地址 outer 0x140000ae018
- value的地址 inner 0x140000ae018
- 1
- value的地址 inner 0x140000ae018
- 2
闭包函数的使用:cron包
func TestChainSkipIfStillRunning(t *testing.T) {
var buf syncWriter
// 装饰者模式,在运行job之前运行一些东西
cron := New(WithChain(SkipIfStillRunning(DiscardLogger)))
cron.Start()
defer cron.Stop()
cron.AddFunc("@every 10s", func() {
fmt.Println("hello world 1")
})
select {
case <-time.After(2 * time.Minute):
if !strings.Contains(buf.String(), "YOLO") {
t.Error("expected a panic to be logged, got none")
}
return
}
}
func SkipIfStillRunning(logger Logger) JobWrapper {
return func(j Job) Job {
var ch = make(chan struct{}, 1)
ch <- struct{}{}
return FuncJob(func() {
select {
case v := <-ch:
defer func() { ch <- v }()
j.Run()
default:
logger.Info("skip")
}
})
}
}
如果当前正在运行,则skip跳过本次运行。使用的是信号量