DAY4 GOLANG (四)包

(创建不同的文件夹,来存放程序文件),不同的包和main函数放在同一层级

Go的每一个文件都属于一个包,go是以包的形式来管理文件和项目目录结构。

不同的包里,可以有相同名字的函数

引入包,import的路径,是src后面的路径


闭包

一个函数和与其相关的引用环境组合的一个整体(实体)

闭包就是能够读取其他函数内部变量的函数。函数和它引用到的变量共同构成闭包。


var n int = 10

return func (x int ) int {

    n= n+ x

    return n

}

返回值是一个匿名函数,但是这个匿名函数引用到函数外的n,因此这个匿名函数就和形成了一个整体,构成闭包。


闭包练习1:

闭包可以保留上次引用的某个值

func makeSuffix(suffixstring)func (string)string {

return func(namestring)string {

if !strings.HasSuffix(name, suffix){

return  name +suffix

}

return name

}

}


闭包练习2

调用闭包,传入一个文件名,如没有后缀,加后缀,如有后缀,返回文件名。

提示:strings.HasSuffix 可以判断某个字符串是否有指定后缀


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

    return func (name string) string {               //如果name没有后缀,加后缀,如有后缀,返回文件名。

        if  !strings.HasSuffix(name,  suffix)  {

        return  name +suffix                            

    }

    return name

     }

}

func main(){

    f2 :=makeSuffix(".jpg")                                              //此处是定义f2这个函数,注意和下面给f2传入数据做对比

    fmt.Println("文件名处理后", f2("winter"))                   //此处是给f2传入值

    fmt.Println("文件名处理后", f2("bird.jpg"))

}     

结果:

文件名处理后 winter.jpg

文件名处理后 bird.jpg


defer

延时机制

func sum(n1 int,n2 int)   int {

    //当执行到defer时,暂时不执行,会将defer后面的语句压入独立的栈(defer栈),也会把相应的值拷贝入栈(里面的值不会改变)

     //当函数执行完毕后,再从栈,按照先入后出的方式出栈,执行

  defer fmt.Println("ok1 n1=", n1)

    defer fmt.Println("ok2 n2=", n2)

    res := n1 + n2

    fmt.Println("ok3 res=",res)

    return res

}

func main() {

    res :=sum(10, 20)

    fmt.Println("res=",res)

}

结果

ok3 res= 30

ok2 n2= 20

ok1 n1= 10

res= 30

defer的价值在,当函数执行完毕后,可以及时的释放函数创建的资源


如:

 func test () {

    file =  openfile(文件名)       //关闭文件资源

    defer file.close()                

    //接其他代码

}


func test() {

    connect = openDatabase()    

    defer connect.close()    //释放数据库资源

   //接其他代码

}


在函数中经常需要创建资源,为了在函数执行完毕后及时的释放资源,所以提供defer(延时机制)

特别是拿资源(文件、数据库连接)的时候,后面添加defer  file.close( )

或获取数据库的链接 ,后面添加defer  connect.close( ), 进行关闭资源。


两种传递方式

1)值传递,传递的是值的拷贝,效率低,但适用于大数据

值类型:基本数据类型 int系列,float系列,bool,string,数组和结构体。

变量直接储存值,内存通常在栈中分配

2)引用传递,传递的是地址的拷贝,效率高,数据量小

引用类型:指针,slice切片,map,管道chan,interface

变量存储的是一个地址,地址对应的空间才是真正存储数据(值),内存通常在堆上分配。


一些细节

-函数字母开头大写代表公有,小写开头代表私有

-在给一个文件打包时,该包对应一个文件夹,文件夹的包名通常和文件所在的文件夹名一致,一般为小写字母

-在import包时,路径从$GOPATH的src下开始,不用带src,编译器会自动从src下开始引入

-Go支持给包取别名

-如果你要编译成一个可执行程序文件,就需要把这个包声明为main ,即package main ,这就是语法规范,

如果你写一个库,包名可以自定义

-文件的包名通常和文件所在的文件夹名一致,一般为小写字母

- 在f函数的调用机制

基本数据类型 一般在栈区,编译器存在一个逃逸分析,引用数据类型一般在堆区。

-赋值语句如 name := " abc " ,可以写在函数体内,不能写在函数体外

你可能感兴趣的:(DAY4 GOLANG (四)包)