【Go】七、包、init函数、匿名函数、闭包

文章目录

1、包

不同的包,不同的功能和业务,互相import

关于包:

go 复制代码
package 包名

注意点:

  • 建议包名和所在文件夹同名
  • main函数一定要放在main包下,否则编译报错
go 复制代码
go run:cannot run non-main package
  • 导入包是:
go 复制代码
//从$GOPATH/src/后开始计算
import "包的路径"

//一次性导入多个
import(
        "fmt"
        "gocode/testproject01/unit5/demo09/crm/dbutils"
)
  • 函数调用时定位到所在的包
  • 一个目录下,不能有重复的函数
  • 包名和文件夹的名字可以不一样。但同一个目录下的源文件,包名的声明必须一致。即你这个随便起了个aaa,那同文件夹下的其他go文件的包名也就是aaa了
  • 给包取别名后,原来的包名不可再使用

2、本质

go里面,包的实质:

  • 在程序层面,所有使用相同 package 包名 的源文件组成的代码模块
  • 在源文件层面就是一个文件夹

3、init函数

  • 包的初始化函数,做一些初始化操作
  • 每个go的源文件都可以包含一个init函数
  • init函数的执行,是在main函数被执行前,被Go自己的运行框架调用
  • 执行时机:全局变量的定义 > init函数 > main函数
  • 多个源文件都有init函数的时候,从main包的import开始,依次执行导入的包的init函数。当然,如果被导入的包里也有在导入别的包,那就像函数调用一样A ⇒ B ⇒ C ⇒ D ,D函数执行完再退回去 ⇒ C ⇒ B ⇒ A

4、匿名函数

如果某个函数只希望调用一次,可用go的匿名函数:

如上,再定义匿名函数的时候直接调用,如此就能保证匿名函数只被调用一次。如果需要被多次调用,可将匿名函数赋值给一个变量(但不常用了,想多次调可直接去定义个普通函数)

最后,如果想要一个匿名函数可以在整个函数中被调用,那就赋值给一个全局变量:

go 复制代码
package main
import "fmt"

var Func01 = func (num1 int,num2 int) int{
        return num1 * num2
}

func main(){       
        result := Func01(3,4)
        fmt.Println(result)
}

5、闭包

闭包即一个函数和起引用的环境组合的一个整体。

go 复制代码
package main
import "fmt"
//函数功能:求和
//函数的名字:getSum 参数为空
//getSum函数返回值为一个函数,这个函数的参数是一个int类型的参数,返回值也是int类型
func getSum() func (int) int {
        var sum int = 0
        return func (num int) int{
                sum = sum + num 
                return sum
        }
}
//闭包:返回的匿名函数+匿名函数以外的变量num
func main(){
        f := getSum()
        fmt.Println(f(1))//1 
        fmt.Println(f(2))//3
        fmt.Println(f(3))//6
        fmt.Println(f(4))//10
}

运行:

go 复制代码
1
3
6
10

可以看到匿名函数中用到了函数以外的变量sum,它两形成闭包。且 匿名函数中引用的那个变量会一直保存在内存中,可以一直使用

闭包本质依旧是一个匿名函数,只是这个函数引入外界的变量/参数
匿名函数+引用的变量/参数 = 闭包

闭包的特点:

  • 返回的是一个匿名函数,但是这个匿名函数引用到函数外的变量/参数 ,因此这个匿名函数就和变量/参数形成一个整体,构成闭包
  • 闭包中使用的变量/参数会一直保存在内存中,所以会一直使用 ⇒ 意味着闭包不可滥用(对内存消耗大)

闭包应用场景:闭包可以保留上次引用的某个值

Demo:

go 复制代码
package main
import "fmt"
//函数功能:求和
//函数的名字:getSum 参数为空
//getSum函数返回值为一个函数,这个函数的参数是一个int类型的参数,返回值也是int类型
func getSum() func (int) int {
        var sum int = 0
        return func (num int) int{
                sum = sum + num 
                return sum
        }
}
//闭包:返回的匿名函数+匿名函数以外的变量num
func main(){
        f := getSum()
        fmt.Println(f(1))//1 
        fmt.Println(f(2))//3
        fmt.Println(f(3))//6
        fmt.Println(f(4))//10
        fmt.Println("----------------------")
        //不用闭包
        fmt.Println(getSum01(0,1))//1
        fmt.Println(getSum01(1,2))//3
        fmt.Println(getSum01(3,3))//6
        fmt.Println(getSum01(6,4))//10
}


func getSum01(sum int,num int) int{
        sum = sum + num
        return sum
}
//不使用闭包的时候:我想保留的值,不可以反复使用
//闭包应用场景:闭包可以保留上次引用的某个值,我们传入一次就可以反复使用了

如上,不用闭包,想达到和上面闭包一样去共用某个值,就很麻烦。

相关推荐
Bony-1 小时前
Go语言反射从入门到进阶
开发语言·后端·golang
每天写点bug2 小时前
【golang】map遍历注意事项
开发语言·算法·golang
tatasix5 小时前
Go Redis实现排行榜
开发语言·redis·golang
Bony-8 小时前
Go语言高并发实战案例分析
开发语言·后端·golang
ac-er88888 小时前
Golang并发机制以及它所使⽤的CSP并发模型
开发语言·后端·golang
Pandaconda8 小时前
【Golang 面试题】每日 3 题(六)
开发语言·笔记·后端·面试·职场和发展·golang·go
峰子201210 小时前
Go语言实现守护进程的挑战
开发语言·后端·面试·架构·golang·go
网络风云1 天前
【魅力golang】之-反射
开发语言·后端·golang
xiaocaibao7772 天前
编程语言的软件工程
开发语言·后端·golang
xiaocaibao7772 天前
Java语言的网络编程
开发语言·后端·golang