先看一段程序

package main

import (
  "fmt"
)

func main() {
   a := []int{1, 2, 3}
   for _, i := range a {
     fmt.Println(i)
     defer p(i)
   }
 }
 
 func p(i int) {
  fmt.Println(i)
 }

运行这段程序,输出结果为

1

2

3

3

2

1

这里就是普通的函数调用,每次调用func p时,完成 i 的值复制,然后打印,此时 i 值复制了3次,分别是1,2,3。由于defer是后进先出,所以执行变成3,2,1

下面我我们用闭包改写下程序:

package main

import (
  "fmt"
)

func main() {
  a := []int{1, 2, 3}
  for _, i := range a {
    fmt.Println(i)
    defer func() {
       fmt.Println(i)
    }()
    }
}

运行这段程序,输出结果为

1

2

3

3

3

3

这个就是闭包的“神奇”之处。闭包里的非传递参数外部变量值是传引用的,在闭包函数里那个i就是外部非闭包函数自己的参数,所以是相当于引用了外部的变量, i 的值执行到第三次是3 ,闭包是地址引用所以打印了3次i地址指向的值,所以是3,3,3

golang的闭包和普通函数调用区别的更多相关文章

  1. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  2. 【GoLang】GoLang 中 make 与 new的区别

    make.new操作 make用于内建类型(map.slice 和channel)的内存分配.new用于各种类型的内存分配. 内建函数new本质上说跟其它语言中的同名函数功能一样:new(T)分配了零 ...

  3. [golang] go的typeswitch guard(类型区别)语法和type assertion(类型断言)语法

    最近在实现golang,看到个go的特性语法: typeswitch guard. typeswitch guard语法如下: package main import "fmt" ...

  4. JavaScript闭包函数&箭头函数调用与执行

    一.标准的闭包函数 //一.标准的闭包函数 function A() { var i=0; ++i; console.log('i : ' + i); return function b() { re ...

  5. Golang两种执行流程以及区别

    Go语言的执行方式有两种,一种是编译后再执行,另一种直接go run执行. 一.先编译后执行 .go文件(源代码)--->go build指令把源代码编译(如果是windows下会编译出一个.e ...

  6. [Golang]-1 Slice与数组的区别

    目录 数组 1.创建数组: 2.数组是值拷贝传递: 切片(slice) 1.首先看看slice的源码结构: 2.slice的创建: 3.slice使用make创建 4.切片作为参数传递 5.Golan ...

  7. golang中闭包讲解

    1. 非闭包时的结果 package main import "fmt" func main() { var funcSlice []func() for i := 0; i &l ...

  8. golang中数组与切片的区别

    初始化:数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变 数组: a := [...],,} a := [],,} 切片: a:= [],,} a := make([]) a := m ...

  9. 【GoLang】golang 中 defer 参数的蹊跷

    参考资料: http://studygolang.com/articles/7994--Defer函数调用参数的求值 golang的闭包和普通函数调用区别:http://studygolang.com ...

随机推荐

  1. Example010实现浏览器兼容改内容的函数,自写

    <!-- 实例010实现浏览器兼容改内容的函数 --> <!DOCTYPE html> <html lang="en"> <head> ...

  2. 每篇半小时1天入门MongoDB——4.MongoDB索引介绍及数据库命令操作

    准备工作 继续连接到mongo C:\Users\zouqi>mongo MongoDB shell version: 3.0.7 connecting to: test 查看数据库和集合 &g ...

  3. JAVA基础——异常详解

    JAVA异常与异常处理详解 一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1 ...

  4. PHP xmapp 下面安装 Composer-Setup.exe

    1.打开PHP配置文件E:\xampp\php\php.ini确认以下模块已开启(移除前面的分号). extension=php_openssl.dll, (php.ini文档里面开启一次就OK了) ...

  5. H3CNE实验:H3C设备文件管理

    第1步:配置文件的管理操作 (1) save [ safely ]--在H3C设备上将当前配置保存到存储介质的根目录下. 快速保存方式:不带 safely 参数. 安全方式:带 safely 参数. ...

  6. jquery 变量和原生js变量的关系

    其实js 变量和 jquery没什么不一样, 也可以直接 var  hhhh=$("header"); 但是当用到用到hhh时依然要用jquery 的方式,而不能js原生的方式.

  7. vijos1101题解

    题目: 研究表明,这种传染病的传播具有两种很特殊的性质: 第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不 得病,或者是XY之间的传播途径被切断,则X就不会得病. 第二是,这种 ...

  8. ARP欺骗分析

    (作者原创,欲转载请说明出处)1.arp介绍    arp:地址解析协议;将IP地址映射为MAC地址.2.为什么要有arp    平时上网我们都知道要有一个IP地址才能上网,那arp用来干嘛的呢?如果 ...

  9. 关于js中的表单事件

    表单结构如下所示: <form > <input type="text" name="txt" id="txt" valu ...

  10. Java 时钟

    <!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...