Go 其他特性
为了保持 Go 语法介绍的完整性,有一些 Go 独有的特性,并没有在前面的章节介绍。说 Go 独有的特性其实并不恰当,因为其他语言并非在语言层面定义上下面的几个特性。
本节想介绍的关键字与函数包括 defer, append, close, make, new, copy, delete
,只有第一个是关键字,后6个都是内置函数。
defer
defer 是 Golang 中的广义的通用析构函数。析构函数是在Java,C++类中所定义的一类在类被销毁时执行收尾的函数。什么叫收尾,就是类似于离家出门前总是要锁门;下班了总是要打卡这样一类,默认都需要在结束时做的事情。在函数结束时,哪些工作需要收尾呢?
- 打开的文件要关闭,不管发生读写任何操作;
- 打开的网络连接要关闭,不管你访问了哪些资源;
- 共享的锁子要解锁,不管你修改了哪些东西;
总之类似于此的公共资源,由你借出最后必然要由你归还。问题是,常常,常常就忘了。如何不忘记呢?就是打开的地方就设置要关闭。defer
就是这样一个关键字,后面接一个函数/方法,表示延时执行,延时作用范围为,延迟到函数发生return
之后动作。例如
filehandle, err := os.Open("FileName")
if err != nil{
return
}
defer filehandle.Close()
defer
有三个重要点需要注意:
- 当defer被声明处时,其参数就会被解析确定
- defer执行顺序为先进后出,即多个defer声明,按照倒叙执行
- defer 语句是在 return 后执行,但defer依然在函数作用范围内。
看下面的例子:
func addself(i int) {
fmt.Println("add_Enter:", i)
i = i + 1
fmt.Println("add_Leave:", i)
}
func addself2(i *int) {
fmt.Println("add_Enter:", *i)
*i = *i + 2
fmt.Println("add_Leave:", *i)
}
func printN(i *int) int {
defer addself(*i)
fmt.Println("Enter:", *i)
*i = *i + 1
fmt.Println("Meddle:", *i)
defer addself2(i)
fmt.Println("Leave:", *i)
return *i
}
func main() {
anum := 10
fmt.Println(printN(&anum))
fmt.Println(anum)
}
/* ---- Result -------------
Enter: 10
Meddle: 11 // printN ++
Leave: 11
add_Enter: 11 // 取printN自加的值作为输入,后面defer先执行
add_Leave: 13
add_Enter: 10 // 取刚刚进入的值作为输入,最后执行
add_Leave: 11
11 // 函数值返回值为 11
13 // i 最终的值为13,已经在确定i返回值之后才执行defer函数
*/
网友评论