GO基础笔记(二) 闭包及其陷阱

GO是支持函数式编程的,在GO中,函数是一等公民,它可以作为变量被赋值,作为参数被传递到其它函数中。

那么既然能够将函数作为变量,GO就一定是支持闭包的。

闭包概念

什么是闭包呢?其实很简单,我们都知道,变量是有其作用域的。例如,在函数中声明定义的变量就只能够在当前函数中使用,当函数结束时,该变量空间就会被释放,外部无法再使用。

但是,闭包允许我们将变量的作用域进行扩充。当我们的函数会返回另外一个函数时(不管是直接返回出去,还是保存在其他变量中间接返回出去),这个被返回的函数如果引用到一些内部的变量,那么这些内部的变量值将会和被返回的函数一起“打包”,作为一个整体返回出去。

这样,在外部,不仅可以使用到被返回的函数,也可以使用到本应该是不可见的,那些被一起打包返回的内部变量的值。

通俗地说,这其实是一个“借刀杀人”的过程。例如你想访问函数fun1的某个内部变量a的值,但是fun1没有直接返回这个值。这在一般情况下就无法实现了:

package main

import "fmt"

func fun1() {
   
	a := 10
	fmt.Println("fun1 a =", a)
}


func main() {
   
	// 这里无法直接访问fun1中的a
	fmt.Println("fun1 a =", a)   // 编译错误:undefined: a
}

但是,如果我们让fun1返回另外一个函数(假设为fun2),这个函数使用到了变量a。因为fun2被返回出去了,外部能够访问了,那么变量a就会和fun2作为闭包一起被返回出去,外部就能获取a的值了。我们通过第三者fun2访问到了a

package main

import "fmt"

// 需要被闭包返回出去的函数
type fun2 func() int

func fun1() fun2 {
   
	a := 10
	return func() int {
   
		// 将fun1中的a返回出去
		return a
	}
}

func main() {
   
	// 先获取fun2
	fun2 := fun1()
	// 从fun2获取a
	a := fun2()

	fmt.Println("a =", a)
}

这就是闭包最简单的用法了。

闭包的作用(通过例子学习)

如果这样,你可能会想:那闭包有什么用呢?我为什么不直接返回a,还需要费劲地通过一个函数来把它返回出去?

当然,上面的例子没有什么意义,只是为了让大家简单地认识闭包。我们来看一个更加具体的例子:通过闭包实现求算斐波那契数列。

和传统的求斐波那契不一样,我们想实现这么个效果:

  • 获取一个fib()函数,每次调用该函数,都能返回下一个斐波那契数。
  • 例如,运行fmt.Println(fib(), fib(),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包函数是指内部函数可以访问外部函数的局部变量,并且在外部函数执行结束后,依然可以访问和修改这些变量。在Go语言中,函数也可以作为返回值返回,形成闭包闭包函数可以用来实现函数式编程的一些特性。 函数式编程是一种编程范式,它将计算过程看作是一系列函数的应用。在函数式编程中,函数被视为一等公民,可以像其他数据类型一样传递、赋值和返回。函数式编程强调使用纯函数,即不依赖于外部状态和副作用的函数,这样可以提高代码的可读性、可维护性和并发性。 在Go语言中,闭包函数和函数式编程可以结合使用。通过闭包函数,我们可以在函数内部定义其他函数,并且这些内部函数可以访问外部函数的局部变量。这样就可以实现一些函数式编程的特性,例如高阶函数、柯里化和函数组合等。 以下是一个示例代码,演示了Go语言中闭包函数和函数式编程的用法: ```go package main import "fmt" // 返回一个闭包函数,用于累加计数 func counter() func() int { count := 0 return func() int { count++ return count } } // 使用高阶函数将一个整数加倍 func double(n int) int { return n * 2 } // 使用高阶函数将两个整数相加 func add(a, b int) int { return a + b } func main() { // 使用闭包函数创建一个计数器 c := counter() // 调用计数器函数,并打印结果 fmt.Println(c()) // 输出: 1 fmt.Println(c()) // 输出: 2 // 使用高阶函数将整数加倍,并打印结果 fmt.Println(double(5)) // 输出: 10 // 使用高阶函数将两个整数相加,并打印结果 fmt.Println(add(3, 4)) // 输出: 7 } ``` 在上面的示例中,`counter`函数返回了一个闭包函数,用于实现简单的计数器。`double`函数和`add`函数都是高阶函数,可以作为参数传递给其他函数使用。这些示例展示了Go语言中闭包函数和函数式编程的一些用法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值