匿名函数与闭包

匿名函数与闭包

匿名函数

  匿名函数是指不需要定义函数名的一种函数实现方式。在Go里面里面可以像普通变量一样被传递或使用,Go语言支持在随时代码块中定义匿名函数。
  匿名函数由一个不带函数名的函数声明和函数体组成,如下所示:

func (a, b int, z float64) bool {
    return a*b < int(z)
}

匿名函数可以直接赋值给一个变量或者直接执行,当然也能够作为另一个函数的返回值使用:

f := func(x, y int) int {
    return x+y
}
func (ch chan int) {
    ch <- ACK
} (reply_chan) 

花括号之后直接跟参数列表表示函数调用

闭包

  • 基本概念

  闭包可以包含自由(未绑定到特定对象)变量的代码块,这些变量不会在这个代码块内或者是任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码为自由变量提供绑定的计算环境(作用域)。

  • 闭包的价值

  闭包的价值在于可以作为函数对象或者匿名函数,对于类型系统而言,这意味着不但要表示数据还要表示代码。意味着这些函数可以储存到变量中作为参数传递给其他函数,最重要的是能够被函数动态的创建和返回。

  • Go语言中的闭包
      Go 语言支持匿名函数,可作为闭包。匿名函数是一个”内联”语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。

以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:

package main

import (
    "fmt"
)

func getSequence() func() int {
    i := 0
    return func() int {
        i++
        return i
    }

}

func main() {
    nextNumber1 := getSequence()

    fmt.Println(nextNumber1())
    fmt.Println(nextNumber1())
    fmt.Println(nextNumber1())

    nextNumber2 := getSequence()

    fmt.Println(nextNumber2())
    fmt.Println(nextNumber2())

}

试想,若是变量 i 定义在这个代码块内(就如同我们常见的一个函数内部定义的局部变量),那么每次函数调用完成后,局部变量的生命周期随之结束,我们看到的运行结果一定是:

1
1
1
1
1

若是这个变量 i 是定于在全局上下文中(我理解就是全局变量),那么这个函数被调用5次的输出一定是:

1
2
3
4
5

但实际上,运行结果:

1
2
3
1
2

  在上面这个示例中,变量nextNumber1 和 nextNumber2 均指向了闭包函数,其数据是完全隔离的,他们都有各自独立的自由 i ,这就是在定义代码块的环境中定义的意思。只要变量nextNumber1 和 nextNumber2 还存在,自由变量 i 就不会被释放掉。
  闭包函数内的局部变量 i 无法通过其他途径进行访问和修改,这保证了 i 的安全性。


组团偷狗


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值