匿名函数
匿名函数是指不需要定义函数名的一种函数实现方式。
在Go语言中,函数可以像普通变量一样被传递或使用,这与C语言的回调函数比较类似。不同的是,Go语言支持随时在代码里定义匿名函数
代码格式
func (参数列表) (返回值列表) { | |
函数体 | |
} |
举例1
// 定义匿名函数并赋值给f变量,参数是变量data,int类型 | |
f := func(data int) { | |
fmt.Println("hello", data) | |
} | |
// 此时f变量的类型是func(), 可以直接调用 | |
f(100) |
举例2
for query := 2; query < 6; query++ { | |
func(q int,w int) { | |
fmt.Println("本次打印是 "+strconv.Itoa(q)) | |
fmt.Println("本次打印是 "+strconv.Itoa(w)) | |
}(3,4) | |
} | |
os.Exit(200) | |
//打印结果 | |
本次打印是 3 | |
本次打印是 4 | |
本次打印是 3 | |
本次打印是 4 | |
本次打印是 3 | |
本次打印是 4 | |
本次打印是 3 | |
本次打印是 4 |
可以看到 q int,w int 是声明的参数,}(3,4) ,3和4 是具体的参数,这就是匿名函数的传参方式
案例3
经常使用的场景
案例1后置函数
最后面的小括号 一定要带,否则就会报错
defer func() { | |
fmt.Println(1) | |
}() |
案例
func NewPool(fn func() (io.Closer, error), size uint) (*Pool, error) { | |
//做了size大小的判断,起码它不能小于或者等于0,否则就会返回错误。 | |
if size <= 0 { | |
return nil, errors.New("size的值太小了。") | |
} | |
return &Pool{ | |
factory: fn, | |
//如果参数正常,就会使用size创建一个有缓冲的通道,来保存资源,并且返回一个资源池的指针。 | |
//有了创建好的资源池,那么我们就可以从中获取资源了。 | |
res: make(chan io.Closer, size), | |
}, nil | |
} | |
//生成数据库连接的方法,以供资源池使用 | |
func createConnection() (io.Closer, error) { | |
//并发安全,给数据库连接生成唯一标志 | |
id := atomic.AddInt32(&idCounter, 1) | |
return &dbConnection{id}, nil | |
} | |
//这里可以把函数作为参数传递过去 | |
p, err := pooltest.NewPool(createConnection, poolRes) | |
//调用函数 | |
p.factory() |
可以看到 调用 factory 函数 需要 p.factory() 而不能使用 p.factory, 小括号代表执行和参数