本章将的关键字有 defer,panic,recover,main,init,import

defer

go语言中有一个不错的设计,就是defer。尤其是调用资源时需要打开和关闭两个选项的时候就能凸显出来

它的作用是将指定的语句在函数结束时执行,没明白?咱们举个例子啊

1
2
3
4
5
main () {
  for i :=0;i < 5 ; i++{
    defer fmt.Println('输出:',i)
  }
}

输出的结果不是01234而是相反的43210,这样就明白它的功能了吧?再举一个常用的例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
func OpenFile() bool{
  file.Open("file/path")

  if condition1 {
    file.Close()
    return false
  }

  if condition2 {
    file.Close()
    return false
  }

  file.Close()
  return true
}

在别的语言中我们打开文件的逻辑大体是这样的,你会发现打开一个文件需要在每个条件结束的时候去再声明关闭它, 这显得语句很臃肿,而且如果我们哪个地方给忘了很可能就造成内存泄漏,但在go中它变的很简单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
func OpenFile() bool{
  file.Open("file/path")
  defer file.Close()
  if condition1 {
    return false
  }

  if condition2 {
    return false
  }
  return true
}

当函数按照从上往下执行的时,执行到最下面准备结束这个函数,go将会再从下往上执行一下标明的defer的命令

panic 和 recover

这两个函数放在一起说,因为他们的作用是相对的

panic会中断控制流程的命令,是go语言的报错机制,一旦执行panic那么当前进程就会终止, 但是我们刚才讲的defer命令还是会执行,等defer执行完了就会结束这个goroutine

recover会恢复panic造成的中断,从而让进程继续进行,而且recover只能在defer中执行,同时在正常进程中执行的recover()将返回false

由于没想到十分合适的场景就先不举例了:p

main 和 init

这两个也能放在一起说

main只能有一个,而且只能在main package当中,而init()每个包里都可以有多个,也可以没有,为了方便维护,建议包里不超过一个init

这两个都是系统自动执行的函数,不用在文件中执行

在平时构建项目的时候我们会导入很多的包(package),多个包中肯定会有重复的,但是不用担心,重复导入的包只会生效一次

main package导入外界的包会优先执行外界包的init和变量初始化,如果外界的包也导入了第三方的包,那么优先执行外界包的第三方包的初始化,再执行外界包的初始化最后执行mian package的初始化

这也很好理解,我们引入包的时候这个包肯定要是完整的形态,为了让他完整就要优先满足它的条件,这也层层向外翻到了最边缘初始化完毕再一层层的向内完成初始化

import

import有几个很方便的特性比如:

1
2
3
4
5
import(
  f "fmt"
  . "fmt"
  _ "fmt"
  )

这三种写法

  1. 第一种是引入别名 fmt.Println 就可以简写成 f.Println
  2. 第二种更厉害了,直接就可以把包名给省去 可以当成自己的方法写成 Println
  3. 第三种其实是引入该包,不直接使用包里的函数,而是调用了该包的init函数