【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
}
//不使用闭包的时候:我想保留的值,不可以反复使用
//闭包应用场景:闭包可以保留上次引用的某个值,我们传入一次就可以反复使用了

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

相关推荐
福大大架构师每日一题1 小时前
ollama v0.30.7 正式发布:Hermes 桌面端落地,接口、文档、底层依赖全方位优化
golang·log4j
不爱编程的小陈4 小时前
深入解析 Go 网络 I/O 的底层引擎:从 epoll 到 netpoll
服务器·网络·golang
何以解忧,唯有..7 小时前
Go 语言数据类型详解:从基础到复合类型
开发语言·golang·mfc
踏着七彩祥云的小丑8 小时前
Go学习第7天:Map集合 + 递归函数 + 类型转换
开发语言·学习·golang·go
何以解忧,唯有..8 小时前
Go语言变量的声明方式详解
开发语言·后端·golang
寂夜了无痕8 小时前
Go 多版本管理工具G 保姆级安装配置教程
golang·go多版本管理
张忠琳9 小时前
【Go 1.26.4】Golang Slice 深度解析
开发语言·后端·golang
张忠琳1 天前
【Go 1.26.4】Golang Channel 深度解析
开发语言·后端·golang
张忠琳1 天前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
何以解忧,唯有..1 天前
Go 语言安装与环境配置完整指南
开发语言·后端·golang