教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang 中的闭包详细解释

golang 中的闭包详细解释

发布时间:2022-02-18   编辑:jiaochengji.com
教程集为您提供golang 中的闭包详细解释等资源,欢迎您收藏本站,我们将为您提供最新的golang 中的闭包详细解释资源

闭包是高级编程语言中的一个常用概念,也是一个比较难以理解的概念。

要解释闭包先要从匿名函数开始

<h3>匿名函数</h3>

匿名函数跟普通函数是一样的只是他没有名字。举个例子可以形象的说明

下面的例子是一个普通的函数定义

<pre><code class="language-Go">func DoStuff() { // Do stuff }</code></pre>

如果我们想把他变成匿名函数,我们首先声明一个func类型的变量,然后就可以把任何匿名函数赋值给它了

<pre><code class="language-Go">var DoStuff func() = func() { // Do stuff }</code></pre>

这两个函数其中一个区别就是匿名函数可以运行的时候随意改变里面的内容。

<pre><code class="language-Go">package main import "fmt" var DoStuff func() = func() { // Do stuff fmt.Println("Doing MAIN stuff!") } func main() { DoStuff() DoStuff = func() { fmt.Println("Doing stuff!") } DoStuff() DoStuff = func() { fmt.Println("Doing other stuff.") } DoStuff() }</code></pre>

运行结果是:

<pre><code class="language-Go">Doing MAIN stuff! Doing stuff! Doing other stuff.</code></pre> <h3>闭包</h3>

闭包是匿名函数的一种特殊类型,它引用在函数本身之外声明的变量。 这也就是说我们在使用函数的时候不是将变量传递给函数,而是使用在函数之外声明的变量。

这与常规函数如何引用全局变量非常相似。 您不是直接将这些变量作为参数传递给函数,而是在调用函数时可以访问它们。

<pre><code class="language-Go">package main import "fmt" func main() { n := 0 counter := func() int { n = 1 return n } fmt.Println(counter()) fmt.Println(counter()) }</code></pre>

输出结果

<pre><code class="language-Go">1 2</code></pre>

上面的例子中并没有传递变量n到匿名函数但是它可以访问并使用这个变量,这样就形成了闭包的概念。

上面的例子有个问题就是在main函数中可以访问并更改变量n,为了隔离n使得其他代码不能访问它,我们要使用闭包的另一个特性就是:即使在别处不再引用,仍可以引用在创建过程中可以访问的变量。听起来有点难以理解举个例子

<pre><code class="language-Go">package main import "fmt" func adder() func(int) int { sum := 0 return func(x int) int { sum = x fmt.Printf("x: %d, addr of x:%p\n", x, &x) fmt.Printf("sum: %d, addr of sum:%p\n", sum, &sum) return sum } } func main() { pos := adder() for i := 0; i < 10; i { fmt.Println( pos(i), ) } }</code></pre>

输出结果

<pre><code class="language-Go"> x: 0, addr of x:0xc0000b6018 sum: 0, addr of sum:0xc0000b6010 0 x: 1, addr of x:0xc0000b6028 sum: 1, addr of sum:0xc0000b6010 1 x: 2, addr of x:0xc0000b6040 sum: 3, addr of sum:0xc0000b6010 3 x: 3, addr of x:0xc0000b6048 sum: 6, addr of sum:0xc0000b6010 6 x: 4, addr of x:0xc0000b6050 sum: 10, addr of sum:0xc0000b6010 10 x: 5, addr of x:0xc0000b6058 sum: 15, addr of sum:0xc0000b6010 15 x: 6, addr of x:0xc0000b6060 sum: 21, addr of sum:0xc0000b6010 21 x: 7, addr of x:0xc0000b6068 sum: 28, addr of sum:0xc0000b6010 28 x: 8, addr of x:0xc0000b6070 sum: 36, addr of sum:0xc0000b6010 36 x: 9, addr of x:0xc0000b6078 sum: 45, addr of sum:0xc0000b6010 45</code></pre>

我们可以在每次adder() 运行中sum的地址是不变的,这也是闭包的特性。这就是在函数调用之间保持数据持久性,同时又将数据与其他代码隔离的方式。

到此这篇关于“golang 中的闭包详细解释”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
谈谈我所理解的闭包,js、php、golang里的closure
golang 中的闭包详细解释
php闭包函数是什么
图解 Go 中的延迟调用 defer
自定义协议/解决tcp粘包问题(golang版本)
Golang中seek使用方法详解
Golang面试题总结
Golang map之reflexivekey函数详解
golang 代码注释规范
Golang Context 原理与实战

[关闭]
~ ~