厚土Go学习笔记 | 26. 函数闭包

如果非必要,尽量不要在程序中使用闭包。

go函数可以是一个闭包。闭包是一个函数值,它引用了函数体之外的变量。这个函数可以对这个变量进行访问和赋值。

展示一个例子

package main

import "fmt"

func adder() func(int) int  {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

运行结果

0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90

函数 adder() 内 return 了一个函数值,这个函数值引用了外部的 sum ,形成了一个闭包。 是不是有点看不懂?

好吧,其实 pos(i) 的这个 i ,是给进了 return func(x int) int 里的 x 了。

我们修改一下上面的代码,增加几个输出语句。然后再看看运行结果。

package main

import "fmt"

func adder() func(int) int  {
    sum := 0
    fmt.Println("外边的sum",sum)
    return func(x int) int {
        fmt.Print("里边的x", x, " --> ")
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

增加了输出的运行结果

外边的sum 0
外边的sum 0
里边的x0 --> 里边的x0 --> 0 0
里边的x1 --> 里边的x-2 --> 1 -2
里边的x2 --> 里边的x-4 --> 3 -6
里边的x3 --> 里边的x-6 --> 6 -12
里边的x4 --> 里边的x-8 --> 10 -20
里边的x5 --> 里边的x-10 --> 15 -30
里边的x6 --> 里边的x-12 --> 21 -42
里边的x7 --> 里边的x-14 --> 28 -56
里边的x8 --> 里边的x-16 --> 36 -72
里边的x9 --> 里边的x-18 --> 45 -90

这次看明白了么?

外边的 sum 那个位置只是被调用时执行了一次, posneg 每次循环给入的变量都在 return func(x int) int 内累加。外面的语句没有再执行。

adder() 返回了 func(int) int

func(int) 返回了 int

于是最后那条语句就是打印出两个整数来。

至于,为什么先打印出 2 条“里边的”,之后才打印出 2 个整数。还记得 go 语言的栈么?就是这个原因了。后进先出,先要分别执行完 pos 和 neg ,才能执行 Println 这句了。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2017-12-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

python基础-数据类型与变量

转载于:廖雪峰的官方网站-python教程 数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值。但是,计算机能处理的远...

38170
来自专栏Coco的专栏

javascript中函数声明和函数表达式浅析

18490
来自专栏水击三千

浅谈JavaScript的函数表达式(闭包)

  前文已经简单的介绍了函数的闭包。函数的闭包就是有权访问另一个函数作用域的函数,也就是函数内部又定义了一个函数。 1 var Super=function(n...

23450
来自专栏老司机的技术博客

人人都能学会的python编程教程2:数据类型和变量

了解一门编程语言最开始就是了解它的数据类型了,python基本的数据类型分为如下几类:

38370
来自专栏小樱的经验随笔

【Java学习笔记之七】java函数的语法规则总结

函数的概述 发现不断进行加法运算,为了提高代码的复用性,就把该功能独立封装成一段独立的小程序,当下次需要执行加法运算的时候,就可以直接调用这个段小程序即可,那么...

34360
来自专栏编程

Python面向对象1:基础介绍+封装特征

目前有三种编程方式: 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封...

22070
来自专栏Python研发

最全Python内置函数

判断真假,  True:真  ,  False:假,   把一个对象转换成bool值

29620
来自专栏小古哥的博客园

JavaScript 正则表达式入门教程

正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串 主要分三个部分:基本语法、RegExp对象的方法、JS中支持正则表达式的String对象方法 一、基...

34830
来自专栏抠抠空间

函数 (一) 基础

一、函数的作用 函数可以让我们代码结构更清晰,而且避免了代码的重复,冗余,使一段代码或者功能可以反复的被调用,大大提高了开发效率 二、函数的定义 def 函数名...

31060
来自专栏码云1024

JAVA 第二天 关键字

30570

扫码关注云+社区

领取腾讯云代金券