5.4 Go 闭包

闭包(closure):是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)

package main

import (
"fmt"
) //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
//函数addUpper返回值是个函数
//返回值是匿名函数 func(int)int
func test() func(int) int {
//定义一个局部变量
n := 10
//返回一个匿名函数
return func(x int) int {
n += x
return n
} } /*
addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计 */ func main() {
//调用addUpper函数,获取返回值
f := test()
//此时f是匿名函数,对其传参调用
fmt.Println(f(50)) //10+50=60
fmt.Println(f(20)) //60+20=80
fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值 f1 := test()
fmt.Println(f1(10))
}

闭包代码修改

package main

import (
"fmt"
) //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
//函数addUpper返回值是个函数
//返回值是匿名函数 func(int)int
func test() func(int) int {
//定义一个局部变量
n := 10
var str = "oldboy"
//返回一个匿名函数
return func(x int) int {
n += x
str += string(36) //36对应的
fmt.Println("此时str值:", str)
return n
} } /*
addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计 */ func main() {
//调用addUpper函数,获取返回值
f := test()
//此时f是匿名函数,对其传参调用
fmt.Println(f(50)) //10+50=60
fmt.Println(f(20)) //60+20=80
fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值 //新的初始化
f1 := test()
fmt.Println(f1(10))
}

2. 闭包实战

package main

import (
"fmt"
"strings"
) /*
1.makeSuffixFunc函数接收一个文件名后缀,如.png,且返回闭包
2.调用闭包,传入文件名前缀,如果没有后缀就添加后缀,返回 文件名.png
3.strings.HasSuffix可以判断指定字符串后缀
*/ func makeSuffixFunc(suffix string) func(string) string {
//返回值闭包函数
return func(filename string) string {
//如果没有xx后缀,执行代码
if !strings.HasSuffix(filename, suffix) {
//则字符串拼接
return filename + suffix
}
//否则有后缀名,则直接返回新文件名
return filename
}
} func main() {
//f1返回的是闭包函数,对此闭包函数进行功能性使用
f1 := makeSuffixFunc(".png") fmt.Println(f1("苍老师")) //没有后缀
fmt.Println("小泽老师.png") //有后缀
}

总结:

1.makeSuffixFunc函数中的变量suffix和返回值匿名函数,组合成了一个闭包
2.由于闭包函数保留了上次引用的值suffix,只需要传入一次,即可反复使用

2.1. 函数式编程

支持将函数作为另一个函数的参数,叫回调函数。

支持将函数作为另一个函数的返回值。

package main

import "fmt"

//闭包函数
//函数体内有局部变量 func adder() func(int) int {
sum := 0
//return 的是一个闭包
return func(v int) int {
//引用自由变量,sum
sum += v
return sum
}
} //递归定义
type iAdder func(int) (int, iAdder) //函数式编程写法,函数+常量
func adder2(base int) iAdder {
return func(v int) (int, iAdder) {
return base + v, adder2(base + v)
}
} func main() {
// a := adder() is trivial and also works.
a := adder2(0)
for i := 0; i < 10; i++ {
var s int
s, a = a(i)
fmt.Printf("0 + 1 + ... + %d = %d\n",
i, s)
}
}

go闭包-斐波那契数列

package main

import "fmt"

// 1,1,2,3,5,8,13,21,34,55...
//
func fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
} } func main() {
f := fibonacci()
//斐波那契数列
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f()) }

2.2. python中闭包

def adder():
sum = 0
def f(value):
nonlocal sum
sum +=value
return sum
return f

5.4 Go 闭包的更多相关文章

  1. 《Web 前端面试指南》1、JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

  2. 干货分享:让你分分钟学会 JS 闭包

    闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...

  3. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. javascript之闭包理解以及应用场景

    半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...

  5. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  6. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  7. JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  8. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  9. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  10. JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

随机推荐

  1. Adobe Flash player 过期

    完美解决问题的办法,在百度中输入 "adobe flash player debugger",如图进入官网 选择对应操作系统的对应版本,下载安装,重启浏览器,一切ok IE内核浏览 ...

  2. 数据库SQL---数据库、基本表、视图、索引的定义、修改、删除

    1.SQL(结构化查询语言)的组成:数据定义语言DDL.数据操纵语言DML.数据控制语言DCL.其他. 2.SQL语言的功能: 1)数据查询:SELECT 2)数据定义:CREATE   DROP  ...

  3. Django入门4: ORM 数据库操作

    大纲 一.DjangoORM 创建基本类型及生成数据库表结构 1.简介 2.创建数据库 表结构 二.Django ORM基本增删改查 1.表数据增删改查 2.表结构修改 三.Django ORM 字段 ...

  4. 记一次Pinpoint监控工具部署过程

    环境:Centos 7.4 X64IP:192.168.1.11 1.配置环境,先安装jdk 到Oracle官网下载安装JDK https://www.oracle.com/technetwork/j ...

  5. Vue.js 条件渲染 v-if、v-show、v-else

    v-if  v-if 完全根据表达式的值在DOM中生成或移除一个元素.如果v-if表达式赋值为false,那么对应的元素就会从DOM中移除:否则,对应元素的一个克隆将被重新插入DOM中. 1 2 3 ...

  6. 啃算法:归并排序及JavaScript实现

    在学习归并排序之前,有必要了解分治法,因为归并排序正是应用了分治模式.(基本定义摘自<算法导论>) 一.分治法 1.思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些 ...

  7. 图论--最短路--Floyd(含路径输出)

    #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define maxn 1005 int D[ma ...

  8. .net core 基于Dapper 的分库分表开源框架(core-data)

    一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...

  9. 关于C primer plus 的学习计划(暂停)

    最近想学数据结构,但是C的基础不够好,想借着C primer plus补一下基础.怎料第一章看的还挺快,到第二章看了二十多天.现在改改阅读方式:每日在这里添加进度,然后精看例题习题和章总结,其它简略看 ...

  10. 【Java新特性】Lambda表达式典型案例,你想要的的都在这儿了!!

    写在前面 不得不说,有些小伙伴的学习热情真高,学完了Lambda表达式的语法,想来几个典型案例再强化下.于是问冰河能否给几个Lambda表达式的典型使用示例.于是乎,便有了这篇文章. 案例一 需求 调 ...