每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用,也就是说init会在main函数之前被调用。
package main
import "fmt"
//init函数,通常可以在init函数中完成初始化工作
func init(){
fmt.Println("init()...")
}
func main(){
fmt.Println("main()...")
}
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函数时,执行流程是怎么样的?
见下图:
Go支持匿名函数,匿名函数就是没有名字的函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用。
在定义匿名函数是就直接调用,这种方式匿名函数只能调用一次。
package main
import "fmt"
func main(){
res := func(n1 int ,n2 int) int {
return n1 + n2
}(10,30)
fmt.Println("res =",res)
}
将匿名函数赋给一个变量(函数变量),在通过该变量来调用匿名函数。
package main
import "fmt"
func main(){
a := func(n1 int, n2 int) int{
return n1 + n2
}
res := a(10,20)
fmt.Println("res =",res)
}
如果将匿名函数赋给一个全局变量,那么这个匿名函数,就成为一个全局匿名函数,可以在程序有效。
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)
}
闭包就是一个函数和与其相关引用环境组合的一个整体。
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))
}
add是一个函数,返回的数据类型是 fun (int) int
可以这样理解:闭包是类,函数是操作,n是字段,函数和它使用到n构成闭包。
当我们反复的调用f函数是,因为n是初始化一次,因此每调用一次就进行累计。
搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。
编写一个函数 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 ,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。大家可以仔细的体会一把!