Go语言函数与指针(三)---闭包

二叶草 2020年2月13日21:58:17函数代码评论阅读模式

一、概念

1、闭包在各种各样计算机语言上都能寻找适用的地区,造成也较为早。闭包(Closure)是词法闭包的通称,就如人们念书情况下学过的结合总闭包的定义一样。对闭包的界定有很多种多样叫法,大致能够 分成下列两大类:

  • 一种说法认为闭包是符合一定条件的函数,比如这样定义:闭包是在其词法上下文中引用了自由变量的函数。
  • 另一种说法认为闭包是有函数和其相关的引用环境组合而成的实体。比如这样定义:在实现深约束时,需要创建一个能显示表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包。即:函数+引用环境=闭包。

2、上面的定义,一个认为闭包是函数,一个认为闭包是函数和环境引用组成的整体。显然第二种说法更确切,闭包只是表现像函数,但实际上不是函数。

  • 函数是一些可执行的代码,这些代码在函数被定义后就确定了,不会再执行时发生变化,所以一个函数只有一个实例。
  • 闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

3、闭包在某些编程语言中被称为“Lambda表达式”。

4、函数本身不存储任何信息,只有与引用环境结合后形成的闭包才具有记忆性,函数是编译器静态的概念,而闭包是运行期动态的概念。

5、对象是附有行为的数据,而闭包是附有数据的行为。

二、闭包的价值

1、加强模块化

  • 闭包有助于模块化编程,它能以简单的方式开发较小的模块,从而提高开发速度和程序的可复用性。可以将模块划分的更小。

2、抽象

  • 闭包是数据和行为的组合,这使得闭包具有较好的抽象能力,

3、简化代码

三、一个编程语言需要哪些特性来支持闭包

1、函数是一阶值,即函数可以作为另一个函数的返回值或者参数,还可以作为一个变量的值;

2、函数可以嵌套定义,即在一个函数内部可以定义另一个函数。

3、允许定义匿名函数。

4、可以捕获引用环境,并把环境和函数代码组成一个可调用的实体。

四、案例1:不使用闭包进行计数

package main
import "fmt"
func main() {  for i:=0;i<10;i++{    fmt.Printf("i=%d t",i)    fmt.Println(add(i))  }}
func add(num int) int {  sum := 0  sum += num  return sum}

输出结果:

i=0   0i=1   1i=2   2i=3   3i=4   4i=5   5i=6   6i=7   7i=8   8i=9   9

可以看出来,sum每次都归零,无法完成我们的计数功能。

2、使用闭包完成计数功能

package mainimport "fmt"func main() {  res := adder()  fmt.Printf("%T n",res)  for i:=0;i<5;i++{    fmt.Printf("i=%d t",i)    fmt.Println(res(i))  }}// using closure// return a functionfunc adder() func(int) int{  sum := 0  res := func(num int) int{    sum += num    return sum  }  return res}

输出结果如下:

func(int) int i=0   0i=1   1i=2   3i=3   6i=4   10

可以看出,res的类型是一个返回值为int的函数,输出的结果,每次都在上一个结果的基础上累加进行计数。

总结:

正常情况下,GC会对我们不用的变量进行清除,保证程序的运行效率。但是,如何识别一个变量是“垃圾”呢,即 没有任何引用指向它,简单的说就是没有任何程序用到它。而现在的 sum虽然是函数内的局部变量,但是adder函数一直被赋值给res变量,导致adder中的sum变量一直被使用,所以sum会一直存在并被进行累加。

本文来源于:Go语言函数与指针(三)---闭包-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言中的常量 函数代码

Go语言中的常量

1 概述 常量,一经定义不可更改的量。功能角度看,当出现不需要被更改的数据时,应该使用常量进行存储,例如圆周率。从语法的角度看,使用常量可以保证数据,在整个运行期间内,不会被更改。例如当前处理器的架构...
Go语言的接口 函数代码

Go语言的接口

Go语言-接口 在Go语言中,一个接口类型总是代表着某一种类型(即所有实现它的类型)的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干方法声明...
Go语言支持的正则语法 函数代码

Go语言支持的正则语法

1 字符 语法 说明 . 任意字符,在单行模式(s标志)下,也可以匹配换行 字符类 否定字符类 d Perl 字符类 D 否定 Perl 字符类 ASCII 字符类 否定 ASCII 字符类 pN U...
Go语言的包管理 函数代码

Go语言的包管理

1 概述 Go 语言的源码复用建立在包(package)基础之上。包通过 package, import, GOPATH 操作完成。 2 main包 Go 语言的入口 main() 函数所在的包(pa...

发表评论