从匿名函数说起

我们先来看看一个常规的有名字的函数是什么样子的,就像下面这样

func myFunc(value string) {
    fmt.Println(value)
}

你可以通过下面的方式调用它

myFunc("我是张三") // 我是张三

现在我们用匿名函数来书写上面的内容

func main() {
	func(value string) {
		fmt.Println(value)
	}("我是张三") // 我是张三
}

在这里有两个要注意的地方:
第一个,匿名函数不能单独使用,也就是说,你不能像开始的 myFunc 一样在外部新建一个函数,匿名函数必须搭配一个有名函数使用,这种搭配是指匿名函数在有名的函数体内,就像上面的匿名函数是在 main 内部。

("我是张三")
函数返回值为函数

匿名函数最常用的适用场景就是作为函数的返回值,这在 go 中是允许的。我们来看下面的代码:

func return_func() func(string) {
    return func(value string){
        fmt.Println(value)
    }
}
return_func
func(string) {
    return func(value string){
        fmt.Println(value)
    }
}

对于 return_func 你可以这样调用

package main

import (
	"fmt"
)

func return_func() func(string) {
	return func(value string) {
		fmt.Println(value)
	}
}

func main() {
	getReturn := return_func() // getReturn 将会获取 return_func 返回的那一大块函数
	getReturn("我是李四") // 我是李四
}

以上便是匿名函数的用法。

golang 中的闭包是什么

闭包就是指一个函数引用了定义在自身函数体之外的变量,这使得采用闭包的函数有点像内部函数,但是使用了闭包的函数可以在它所引用的函数生命周期结束后,依然可以使用该引用函数的变量。

下面我们就来看代码理解一下。我们重新书写一个函数 return_int

func return_int() func() int{
	val := 0
    return func(){
        val++
        return val
    }
}

这个 return_int 和之前的 return_func 本质上没有什么区别,下面我们来执行一下

package main

import (
	"fmt"
)

func return_int() func() int {
	val := 0
	return func() int {
		val++
		return val
	}
}

func main() {
	getReturn := return_int()
	fmt.Println(getReturn()) // 1
	fmt.Println(getReturn()) // 2
	fmt.Println(getReturn()) // 3
}

可以看到,return_int 在赋值给 getReturn 后就已经结束了,然后在执行 getReturn 时(getReturn 就是那一块匿名函数作为返回值的部分),依然可以使用 val,要知道 val 是 return_int 的变量,由此可见,闭包延长了使用的外部函数变量的寿命。
在这里插入图片描述

总结
  1. 匿名函数就是一个没有名字的函数,常用于函数返回值的情况
  2. 闭包就是一个函数引用自身函数体之外的另一个函数中的变量
参考