Golang基础-函数二(八)

文章目录

    • 6.包的引入
    • 7.包的细节1
    • 8.包的细节2
    • 9.init函数
    • 10.匿名函数
    • 11.闭包
    • 12.defer关键字

6.包的引入

【1】使用包的原因:
(1)我们不可能把所有的函数放在同一个源文件中,可以分门别类的把函数放在不同的原文件中
Golang基础-函数二(八)_第1张图片

2)解决同名问题:两个人都想定义一个同名的函数,在同一个文件中是不可以定义相同名字的函数的。此时可以用包来区分

【2】案例展示包:
项目的结构:

Golang基础-函数二(八)_第2张图片

代码展示:

//main.go
package main //1.package进行包的声明,建议:包的声明这个包和所在的文件夹同名
//2.main包是程序的入口包,一般main函数会放在这个包下

//import "fmt"
//3.包名是从$GOPATH/src/后开始计算的,使用/进行路劲分隔
//import "gocode/testproject01/unit5/demo9/crm/dbutils"
//如果有多个包需要导入,建议一次性导入
import (
	"fmt"
	"gocode/testproject01/unit5/demo9/crm/dbutils"
)
func main(){
	fmt.Println("Hello ,这是main函数的执行")
	dbutils.GetConn()//4.在函数调用的时候前面要定位到所在的包
}
//dbutils.go
package dbutils
import "fmt"

func GetConn(){//5.首字母大写,可以被其他包使用
    fmt.Println("执行了dbutils包下的getConn函数")
}

Golang基础-函数二(八)_第3张图片
Golang基础-函数二(八)_第4张图片

7.包的细节1

1.package进行包的声明,建议:包的声明这个包和所在的文件夹同名

Golang基础-函数二(八)_第5张图片

2.main包是程序的入口包,一般main函数会放在这个包下
main函数一定要放在main包下,否则不能编译执行

在这里插入图片描述

3.打包语法:
package 包名
4.引入包的语法:import “包的路径”
包名是从$GOPATH/src/后开始计算的,使用/进行路径分隔。
Golang基础-函数二(八)_第6张图片

Golang基础-函数二(八)_第7张图片

5.如果有多个包,建议一次性导入,格式如下:

import(
        "fmt"
        "gocode/testproject01/unit5/demo09/crm/dbutils"
)

6.在函数调用的时候前面要定位到所在的包

Golang基础-函数二(八)_第8张图片

7.函数名,变量名首字母大写,函数,变量可以被其它包访问
Golang基础-函数二(八)_第9张图片

8.一个目录下不能有重复的函数

Golang基础-函数二(八)_第10张图片

9.包名和文件夹的名字,可以不一样

Golang基础-函数二(八)_第11张图片
Golang基础-函数二(八)_第12张图片

10.一个目录下的同级文件归属一个包
同级别的源文件的包的声明必须一致

Golang基础-函数二(八)_第13张图片
Golang基础-函数二(八)_第14张图片

11.包到底是什么:
(1)在程序层面,所有使用相同 package 包名 的源文件组成的代码模块
(2)在源文件层面就是一个文件夹

8.包的细节2

12.可以给包取别名,取别名后,原来的包名就不能使用了
Golang基础-函数二(八)_第15张图片

9.init函数

【1】init函数:初始化函数,可以用来进行一些初始化的操作
每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用。

package main
import "fmt"

func init(){
	fmt.Println("main.go中的init函数被执行")
}

func main(){
	fmt.Println("main函数被执行")
}

Golang基础-函数二(八)_第16张图片

【2】全局变量定义,init函数,main函数的执行流程?

package main
import (
	"fmt"
	"gocode/testproject01/unit5/demo10/testutils"
)

var num int = test()


func test() int{
	fmt.Println("test函数被执行")
	return 10
}
func init(){
	fmt.Println("main.go中的init函数被执行")
}

func main(){
	fmt.Println("main函数被执行")
}

Golang基础-函数二(八)_第17张图片

【3】多个源文件都有init函数的时候,如何执行:

package testutils
import "fmt"

var Age int
var Sex string
var Name string

//定义一个init函数对变量进行初始化赋值:
func init(){
	fmt.Println("testutils中的init函数被执行了")
	Age = 19
	Sex = "女"
	Name = "丽丽"
}
package main
import (
	"fmt"
	"gocode/testproject01/unit5/demo10/testutils"
)

var num int = test()


func test() int{
	fmt.Println("test函数被执行")
	return 10
}
func init(){
	fmt.Println("main.go中的init函数被执行")
}

func main(){
	fmt.Println("main函数被执行")
	fmt.Println("Age= ",testutils.Age,"Sex=",testutils.Sex,"Name=",testutils.Name)
}

Golang基础-函数二(八)_第18张图片
Golang基础-函数二(八)_第19张图片

执行结果:

Golang基础-函数二(八)_第20张图片

执行过程:

Golang基础-函数二(八)_第21张图片

10.匿名函数

【1】Go支持匿名函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数
【2】匿名函数使用方式:
(1)在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次(用的多)
Golang基础-函数二(八)_第22张图片

(2)将匿名函数赋给一个变量(该变量就是函数变量了),再通过该变量来调用匿名函数(用的少)

package main
import "fmt"

func main(){
	//定义匿名函数:定义的同时调用
	result := func (num1 int,num2 int) int{
		return num1 + num2
	}(10,20)

	fmt.Println(result)

	//将匿名函数赋给一个变量,这个变量实际就是函数类型的变量
	//sub等价于匿名函数
	sub := func (num1 int,num2 int) int{
		return num1 - num2
	}

	//直接调用sub
	result01 := sub(30,70)
	fmt.Println(result01)
                    
    result02 := sub(30,70)
    fmt.Println(result02)
}

Golang基础-函数二(八)_第23张图片

【3】如何让一个匿名函数,可以在整个程序中有效呢?将匿名函数给一个全局变量就可以了

package main
import "fmt"

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

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

匿名函数实验的总代码

package main
import "fmt"

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

func main(){
	//定义匿名函数:定义的同时调用
	result := func (num1 int,num2 int) int{
		return num1 + num2
	}(10,20)

	fmt.Println(result)

	//将匿名函数赋给一个变量,这个变量实际就是函数类型的变量
	//sub等价于匿名函数
	sub := func (num1 int,num2 int) int{
		return num1 - num2
	}

	//直接调用sub
	result01 := sub(30,70)
	fmt.Println(result01)

	result02 := sub(30,70)
	fmt.Println(result02)

	result03 := Func01(3,4)
	fmt.Println(result03)
}

11.闭包

【1】什么是闭包:
闭包就是一个函数和与其相关的引用环境组合的一个整体

【2】案例展示:

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))
	fmt.Println(f(3))
	fmt.Println(f(4))
}

Golang基础-函数二(八)_第24张图片

感受:匿名函数中引用的那个变量会一直保存在内存中,可以一直使用

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

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

【5】不使用闭包可以吗?

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))
	fmt.Println(f(3))
	fmt.Println(f(4))

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

Golang基础-函数二(八)_第25张图片

12.defer关键字

【1】defer关键字的作用:
在函数中,程序员经常需要创建资源,为了在函数执行完毕后,及时的释放资源,Go的设计者提供defer关键字

【2】案例展示:

package main
import "fmt"

func main(){
     
	fmt.Println(add(30,60))
}

func add(num1 int ,num2 int) int{
     
	//在Golang中,程序遇到defer关键字,不会立即执行defer后的语句,而是将defer后的语句压入一个栈中,然后继续执行函数后面的语句
	defer fmt.Println("num1=",num1)
	defer fmt.Println("num2=",num2)
	//栈的特点是:先进后出
	//在函数执行完毕以后,从栈中取除语句开始执行,安照先进后出的规则执行语句
	var sum int = num1 + num2
	fmt.Println("sum=",sum)
	return sum
}

Golang基础-函数二(八)_第26张图片

【3】代码变动一下,再次看结果:
Golang基础-函数二(八)_第27张图片

发现:遇到defer关键字,会将后面的代码语句压入栈中,也会将相关的值同时拷贝入栈中,不会随着函数后面的变化而变化。

【4】defer应用场景:
比如你想关闭某个使用的资源,在使用的时候直接随手defer,因为defer有延迟执行机制(函数执行完毕再执行defer压入栈的语句),
所以你用完随手写了关闭,比较省心,省事

你可能感兴趣的:(GoLang,golang)