go语言中的defer关键字

Elina ·
更新时间:2024-09-21
· 1186 次阅读

我是谁

defer - 顾名思义翻译过来叫 延迟, 所以我们通常称呼 defer func() 这样 defer 后面紧跟的函数为 延迟函数.

作者注: 不过从实际应用来讲, 延迟函数通常用来做一些函数最终返回前的一些收尾工作, 所以称呼为收尾函数其实更贴切.

三围几何

defer 有其独特的一面, 了解其个性, 才能更好的下手。

延迟性

顾名思义, 既然叫延迟函数, 那么肯定具备延迟性.

我们来看看怎么个延迟法,

defer_defer.go

// defer_defer.go package main import ( "fmt" ) func main() { foo() } func foo() { fmt.Println(1) defer fmt.Println(2) fmt.Println(3) } // go run defer_defer.go // 1 // 3 // 2

可以看到 defer 定义的延迟函数最后才执行.

再来个例子, 如果一个函数内出现多个延迟函数, 延迟函数的执行顺序又是怎么样的呢?

defer_filo.go

// defer_filo.go package main import ( "fmt" ) func main() { foo() } func foo() { defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) } // go run defer_filo.go // 3 // 2 // 1

可以看到先定义的延迟函数后执行, 后定义的延迟函数先执行, 符合栈 (stack) 的先进后出 (FILO) 原则.

影响性

直接看代码,

defer_impact.go

// defer_impact.go package main import ( "fmt" ) func main() { fmt.Println(foo()) } func foo() (result int) { defer func() { result++ }() return 0 } // go run defer_defer.go // 1

结果是不是跟想象有点不一样? 上述 foo() 可以改写为下:

func foo() (result int) { result = 0 result++ return }

go 中的 return 语句不是原子操作.

go 中 return 语句的操作过程为:

设置返回值

执行延迟函数

真正 return

所以延迟函数会影响主函数的返回值, 当然还要区分具名返回值/匿名返回值, 后话再说.

确定性

延迟函数的参数值, 在延迟函数首次出现时就确定了, 不受后续操作的影响.

我们来个例子:

defer_parameters.go

// defer_parameters.go package main import ( "fmt" ) func main() { foo() } func foo() { number := 1 defer fmt.Println(number) number = 2 return } // go run defer_parameters.go // 1 能做啥

打开数据链接, 要记得关闭, 可以用 defer

操作完内存资源, 要记得释放, 可以用 defer

想改变主函数的具名返回值, 可以用 defer - 通常不会这么干

想奇淫技巧, 可以用 defer - 偶尔 show 偶尔爽, 一直 show 一直爽

想搞事情, 可以用 defer - 请自行确保生命和财产安全

...

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对软件开发网的支持。如果你想了解更多相关内容请查看下面相关链接



GO defer go语言

需要 登录 后方可回复, 如果你还没有账号请 注册新账号