Go: 关于匿名函数

有几个同事刚学 Go 语言,最近对匿名函数的使用有些困惑,就问了下我,我做了一些解答,后来想了下,还是可以整理记录下。

例子大致是这样:

package main

import "fmt"

func main() {

	innerFun := func(i int) {
		fmt.Println(i)
	}

	useInnerFun(innerFun)
}

func useInnerFun(f func(i int)) {
	f(1)
}

当时他们认为说这个匿名函数应该在 main 函数里就已经调用了,但其实不然,在 main 函数里只是做了定义,而不是发生了调用,真正的调用是在 useInnerFun 里。

我想造成困惑的原因可能有几个点,一个是对概念的理解还不太清楚,一个是有时我们单独地去看待一个东西,没有跟别的一些东西发生联系,就容易陷入其中,那么在这里就是没拿它跟具名函数做对比。

我想或许可以通过下面几种方法来帮助他们理解这个东西。

首先我们观察定义一个具名函数和一个匿名函数时的操作过程,不管我们写哪种都好,它们其实都很像,有个 func 的关键词,然后括号用于承载参数,再用大括号包裹函数体,唯一的区别就是在外部定义的具名函数,有个具体的名字,这样我们在别的函数调用的时候,就可以指明来用。

而匿名函数只是把这个具体的名字拿出来,让函数定义本身更纯粹。

// 具名函数
func NamedFun(i int) {
	fmt.Println(i)
}

func main(){
     // 匿名函数的定义如下,但注意这里是会报错的,错不在于定义上有问题,而是 go 的规范,提示的错误是未被使用
     func(i int) {
	 	fmt.Println(i)
	 }
}

接着我们可以看下我们是如何调用一个函数的,对于具名函数,我们需要写出它的方法名,然后加上括号和实参,表示进行了调用。

func main(){

    NamedFun(1)

}

// 具名函数
func NamedFun(i int) {
	fmt.Println(i)
}

那么对于匿名函数,其实也一样,我们只要知道,函数名其实是一个符号,它代表的是背后的一个 func 函数。匿名函数的道理也是如此,只是它的表现形式会更为多样:

func main(){
    // 匿名函数
    // 1. 通过给这个匿名函数指定一个变量名 anonyFun,就相当于具名函数的方法名,同样的通过括号和实参,实现调用
    anonyFun := func(i int) {
		fmt.Println(i)
	} 
    anonyFun(1)

    // 2. 或者直接定义后立即使用
    func(i int) {
		fmt.Println(i)
	}(1)

    // 3. 或者作为另外一个函数的参数传入
    useAnonyFun(anonyFun)
    // 或
    useAnonyFun(func(i int) {
		fmt.Println(i)
	})
    
}

func useAnonyFun(anony func(i int)) {
	anony(1)
}

但不管怎么样,我们都能看到,如果要让一个函数发挥作用,那么就是函数/函数名+括号+实参。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值