Golang的闭包和匿名函数
2023-12-16 13:44 abce 阅读(360) 评论(0) 收藏 举报Golang语言支持匿名函数,这些匿名函数也被称为闭包。匿名函数是一种特殊类型的函数,它没有名称,而闭包可以看作是一种特殊类型的匿名函数,尽管在实践中有微小的区别。
Golang 中的匿名函数
匿名函数也可以称为字面函数、lambda 函数或闭包。闭包的概念源于 lambda 计算中表达式的数学评估。从技术上讲,匿名函数和闭包之间有一个微妙的区别:匿名函数是一个没有名称的函数,而闭包是一个函数的实例。然而,要在 Golang 中实际实现闭包,编写匿名函数是关键。
如何创建闭包
通过匿名函数,我们可以在任何表达式中编写表示函数值的字面函数。其语法与命名的函数(常规函数)非常相似,只是在 func 关键字之后没有名称。因此,如果 Go 开发人员不想给函数命名,那么我们可以创建匿名函数。
以下是在 Go 中创建闭包的语法和示例代码:
func (a, b int){ return a+b }
请注意,这种函数不能单独编写,因此在赋值时要声明一个变量,如:
sum := func(a, b int) int { return a + b }
fmt.Println(sum(1, 2))
函数的调用方式为 sum(1,2)。
也可以在定义时直接调用,如下所示:
sum := func(a, b int) int { return a + b }(1, 2)
fmt.Println(sum)
下面是另一个求整数之和的示例
--在这个代码示例中,我们可以将匿名函数编写如下:
func() {
sum := 0
for i := 0; i < 100; i++ {
sum += i
}
}()
func 关键字后的第一个括号 () 是参数列表,闭包没有名称。闭包的主体由大括号 {} 组成,最后一对小括号 () 表示函数调用。
闭包如何返回值
闭包或匿名函数可以创建带参数或不带参数的函数,但我们能从这样的函数中返回值吗?
下面是一个如何从 Go 中的闭包返回值的示例。让我们编写一个函数,每次调用都返回下一个斐波那契数字:
package main
import "fmt"
func fibonacci() func() int {
a, b := -1, 1
return func() int {
a, b = b, a+b
return b
}
}
func main() {
fibo := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(fibo())
}
}
函数返回另外一个函数
已声明的局部变量的作用域有限,只存在于声明该变量的程序块或函数中。
当变量失去作用域时,就会被刷出内存。不过,在闭包的帮助下,即使在执行程序离开代码块后,局部变量仍有可能继续存在。我们可以使用 Go 闭包编写一个返回另一个函数的函数。下面是一个例子:
func square() func(num int) int {
return func(num int) int {
return num * num
}
}
func mul(n1 int) func(n2 int) int {
return func(n2 int) int {
return n1 * n2
}
}
func main() {
// make an square function, give it a name f2, and call it:
f2 := square()
fmt.Printf("Call square for 3 gives: %v\n", f2(3))
// make a special mul function, n1 gets value 3:
f3 := mul(3)
fmt.Printf("The result is: %v\n", f3(3))
}
将匿名函数作为参数传递
下面的示例程序说明了如何在 Go 中将匿名函数作为参数传递给另一个函数。同时请注意,匿名函数在变量上闭包,形成一个闭包:
package main
import (
"fmt"
"math/rand"
"time"
)
func xyValues(f func(max int) (int, int)) {
x, y := f(35)
fmt.Println(x, y)
x, y = f(50)
fmt.Println(x, y)
}
func main() {
fn := func(max int) (int, int) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
x_axis := r.Intn(max)
y_axis := r.Intn(max)
return x_axis, y_axis
}
xyValues(fn)
x, y := fn(20)
fmt.Println(x, y)
}
在上述代码示例中,匿名函数是在主函数中声明的。它只是在作为函数参数传入的最大值范围内,为 x_axis 和 y_axis 生成两个随机整数,并返回。
匿名函数被赋值给变量 fn,并将函数值传递给另一个名为 xyValues 的函数。xyValues 函数反过来接收一个函数作为参数,即 fn 函数参数。
有几点需要注意:在 main 中,匿名函数的值有两个用途:
·将函数值作为参数传递,调用 xyValues 函数。
·通过提供一个值作为参数,直接调用函数值。

浙公网安备 33010602011771号