登录
首页 >  Golang >  Go教程

go语言中的defer关键字

来源:脚本之家

时间:2023-02-17 16:11:11 150浏览 收藏

怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《go语言中的defer关键字》,涉及到defer、关键字、go,有需要的可以收藏一下

我是谁

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 - 请自行确保生命和财产安全
  • ...

文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《go语言中的defer关键字》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表