Go函数
Go语言 延迟调用(defer)
- defer特性: - 关键字 defer 用于注册延迟调用。 - 这些调用直到 return 前才被执。因此,可以用来做资源清理。 - 多个defer语句,按先进后出的方式执行。 - defer语句中的变量,在defer声明时就决定了。 - defer 是先进后出。这是因为后面的语句会依赖前面的资源,因此如果先前面的资源先释放了,后面的语句就没法执行了。 - defer用途: - 关闭文件句柄 - 锁资源释放 - 数据库连接释放 - 例子 ```go func main() { var whatever [5]struct{} for i := range whatever { defer fmt.Println(i) // 4 3 2 1 0 } } ``` - defer 碰上闭包 ```go //也就是说函数正常执行,由于闭包用到的变量 i 在执行的时候已经变成4,所以输出全都是4. func main() { var whatever [5]struct{} for i := range whatever { defer func() { fmt.Println(i) }() //4 4 4 4 4 } } ``` - 多个 defer 注册,按 FILO 次序执行 ( 先进后出 )。哪怕函数或某个延迟调用发生错误,这些调用依旧会被执行。 ```go func main() { defer println("a") defer println("b") defer func() { println(100 / 0) // div0 异常未被捕获,逐步往外传递,最终终止进程。 }() defer println("c") } //输出结果: c b a panic: runtime error: integer divide by zero ``` ## defer f.Close defer后面的语句在执行的时候,函数调用的参数会被保存起来,但是不执行。也就是复制了一份。但是并没有说struct这里的this指针如何处理,通过这个例子可以看出go语言并没有把这个明确写出来的this指针当作参数来看待。 ```go type Test struct { name string } func (t *Test) Close() { fmt.Println(t.name, " closed") } func main() { ts := []Test{{"a"}, {"b"}, {"c"}} for _, t := range ts { defer t.Close() } } //输出结果: c closed c closed c closed ``` ```go type Test struct { name string } func (t *Test) Close() { fmt.Println(t.name, " closed") } func Close(t Test) { t.Close() } func main() { ts := []Test{{"a"}, {"b"}, {"c"}} for _, t := range ts { defer Close(t) } } //输出结果: c closed b closed a closed ``` ```go type Test struct { name string } func (t *Test) Close() { fmt.Println(t.name, " closed") } func main() { ts := []Test{{"a"}, {"b"}, {"c"}} for _, t := range ts { t2 := t defer t2.Close() } } //输出结果: c closed b closed a closed ```
顶部
收展
底部
[TOC]
目录
Go语言 函数
Go语言 方法
Go语言 延迟调用(defer)
Go语言 异常处理
相关推荐
Go基础
Go数据类型
Go面向对象
Go并发编程
Go数据操作