Golang学习之路— init函数、匿名函数、闭包

init函数、匿名函数、闭包

  • init函数
    • 1、 基本介绍
    • 2、案例说明
    • 3、 init函数的注意事项
  • 匿名函数
    • 1、基本介绍
    • 2、匿名函数使用方式
      • 方式1
      • 方式2
    • 3、全局匿名函数
  • 闭包
    • 1、闭包的介绍
    • 2、案例演示
    • 3、闭包的实践

init函数

1、 基本介绍

每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用,也就是说init会在main函数之前被调用。

2、案例说明

package main
import "fmt"
 
//init函数,通常可以在init函数中完成初始化工作
func init(){
     
	fmt.Println("init()...")
}

func main(){
     
	fmt.Println("main()...")
}

运行结果:
在这里插入图片描述

3、 init函数的注意事项

1、如果一个文件同时包含全局变量定义,init函数和main函数,则执行的流程为:全局变量定义-》init函数-》main函数。

package main
import "fmt"
 
var age  = test()
//init函数,通常可以在init函数中完成初始化工作
func init(){
     
	fmt.Println("init()...")
}

func test() int{
     
	fmt.Println("test()...")
	return 20
}
func main(){
     
	fmt.Println("main()...")
}

运行结果:
在这里插入图片描述
2、面试题:案例如果main.go和utils.go中都含有变量定义,init函数时,执行流程是怎么样的?
见下图:
Golang学习之路— init函数、匿名函数、闭包_第1张图片

匿名函数

1、基本介绍

Go支持匿名函数,匿名函数就是没有名字的函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用。

2、匿名函数使用方式

方式1

在定义匿名函数是就直接调用,这种方式匿名函数只能调用一次。

package main
import "fmt"
 
func main(){
     
	
	res := func(n1 int ,n2 int) int {
     
		return n1 + n2
	}(10,30)
	fmt.Println("res =",res)
}

运行结果:
在这里插入图片描述

方式2

将匿名函数赋给一个变量(函数变量),在通过该变量来调用匿名函数。

package main
import "fmt"
 
func main(){
     
	
	
	a := func(n1 int, n2 int) int{
     
		return n1 + n2
	}
	res := a(10,20)
	fmt.Println("res =",res)
}

运行结果:
在这里插入图片描述

3、全局匿名函数

如果将匿名函数赋给一个全局变量,那么这个匿名函数,就成为一个全局匿名函数,可以在程序有效。

package main
import "fmt"

var (
	Fun = func(n1 int, n2 int) int{
     
		return  n1 + n2
	}
)
 
func main(){
     
	
	//全局匿名函数的使用
	res := Fun(15, 10)
	fmt.Println("res =",res)
}

运行结果:
在这里插入图片描述

闭包

1、闭包的介绍

闭包就是一个函数和与其相关引用环境组合的一个整体。

2、案例演示

package main
import "fmt"

//累加器
func add() func (int) int{
     
	var n int = 10
	return func(x int) int{
     
		n = n + x
		return n
	}
}
 
func main(){
     
	
	f := add()
	fmt.Println(f(1))
	fmt.Println(f(2))
	fmt.Println(f(3))

}

运行结果:
在这里插入图片描述
说明:

  1. add是一个函数,返回的数据类型是 fun (int) int

  2. Golang学习之路— init函数、匿名函数、闭包_第2张图片
    返回的是一个匿名函数,但是这个匿名函数引用到函数外的n,因此这个匿名函数就和n形成了一个整体,构成闭包。

  3. 可以这样理解:闭包是类,函数是操作,n是字段,函数和它使用到n构成闭包。

  4. 当我们反复的调用f函数是,因为n是初始化一次,因此每调用一次就进行累计。

  5. 搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。

3、闭包的实践

编写一个函数 makeSuffix(suffix string)可以接收一个文件后缀名(比如.jpg),并返回一个闭包。调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg) ,则返回文件名.jpg,如果已经有.jpg后缀,则返回原文件名。要求使用闭包的方式完成。
代码:

package main
import (
	"fmt"
	"strings"
)

func makeSuffix(suffix string) func (string) string{
     

	return func (name string) string{
     
		if !strings.HasSuffix(name,suffix){
     
			return name + suffix
		}
		return name
	}
}
 
func main(){
     
	
	f := makeSuffix(".jpg")
	fmt.Println("文件名处理后=",f("abc"))
	fmt.Println("文件名处理后=",f("zxy.jpg"))

}

运行结果:
在这里插入图片描述
说明:
1、返回的匿名函数和 makeSuffix (suffix string)的 suffix变量组合成一个闭包,因为返回的函数引用到suffix这个变量。
2、我们体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入后缀名,比如jpg ,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把!

你可能感兴趣的