Go学习——一篇文章弄懂匿名函数、闭包及之间的关系

目录

1.为什么会有匿名函数?

2.闭包


1.为什么会有匿名函数?

        在定义函数时,不能在函数内部再定义一个函数,如果我们想要在一个函数内部再封装一个方法,就需要使用到匿名函数。

        匿名函数即没有名字的函数,一个函数内部的匿名函数可以访问到这个外部函数中的变量。

        下面使用一个例子来说明匿名函数的使用:

package main

import "fmt"

func main() {
	var num int
	num = 9
	//无参匿名函数
	f := func() {
		num++
		fmt.Println(num)
	}
	//f()
	//将函数当做变量进行传递和调用
	type FuncType func()
	var f1 FuncType
	f1 = f
	f1()

	//有参匿名函数
	f2 := func(a, b int) {
		var sum int
		sum = a + b
		fmt.Println(sum)
	}
	//f2(1, 2)
	//此时对应的func也需要改变
	type FuncType2 func(a, b int)
	var f3 FuncType2
	f3 = f2
	f3(1, 2)

	//有返回值的匿名函数,直接接受的是函数返回值
	x, y := func(i, j int) (max, min int) {
		max = i
		min = j
		return
	}(100, 200)
	fmt.Println(x, y)

	//匿名函数主要实现的功能是闭包,闭包就是在一个函数中去访问另一个函数作用域中的变量

}

        在这个例子中我们在外部函数中定义了一个变量num,然后定义了一个匿名函数,对num变量加+1。

        我们使用匿名函数时若匿名函数没有返回值(对应例子中的第一个匿名函数),我们需要使用一个变量f接受这个匿名函数,f此时的类型即为这个匿名函数。于是我们通过type关键字重命名这个匿名函数func()为FuncType,并初始化一个FuncType类型的变量,这个变量可以接受f,然后通过f1()调用这个匿名函数。结果为10,说明匿名函数成功访问到变量num。

        对于有参匿名函数使用方式与无参匿名函数相同 ,如例子中的第二个匿名函数

//有参匿名函数
	f2 := func(a, b int) {
		var sum int
		sum = a + b
		fmt.Println(sum)
	}
	//f2(1, 2)
	//此时对应的func也需要改变
	type FuncType2 func(a, b int)
	var f3 FuncType2
	f3 = f2
	f3(1, 2)

        对于有返回值的匿名函数,我们直接接受函数返回值即可,不需要重新调用。如:

//有返回值的匿名函数,直接接受的是函数返回值
	x, y := func(i, j int) (max, min int) {
		max = i
		min = j
		return
	}(100, 200)
	fmt.Println(x, y)

2.闭包

        匿名函数主要实现的功能是闭包,闭包就是在一个函数中去访问另一个函数作用域中的变量。这里匿名函数和其对应的外部函数就是这个闭包关系。

        我们在一个函数中返回一个匿名函数即可实现闭包。例如:

func test1() func() int {
	var x int
	return func() int {
		x++
		return x
	}
}

        在这个例子中,test1的返回值类型为func() int,其内部的匿名函数类型为func() int,接受的参数为test1中的变量x,通过这种方式将test1的返回值用一个变量接受后,多次调用这个变量(返回的匿名函数)不会导致x重新初始化。

func main() {
	f := test1()
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
}

 打印结果为1,2,3,说明多次调用函数f共用了同一个变量x。

作为对比,这里在创建一个没有闭包而定函数test:

func test() int {
	var x int
	x++
	return x
}

func main() {

	//这种情况没有使用闭包,每次调用test()都会重新初始化x,导致x始终为1
	fmt.Println(test())
	fmt.Println(test())
	fmt.Println(test())

}

打印结果为1,1,1,说明每次调用test函数都会重新初始化函数内部的变量。

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值