小编给大家分享一下golang中defer预计算参数怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!什么是deferdefer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数
小编给大家分享一下golang中defer预计算参数怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
defer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也可以说是运行到最外层方法体的"}"时调用。我们经常用他来做一些资源的释放,比如关闭io操作
func doSomething(fileName string) { file,err := os.Open(fileName) if err != nil { panic(err) } defer file.Close()}
defer 可以保证方法可以在外围函数返回之前调用。有点像其他言的 try finally
try{}finally{}
Go 语言中所有的函数调用都是传值的,虽然 defer 是关键字,但是也继承了这个特性。假设我们想要计算 main 函数运行的时间,可能会写出以下的代码:
package mainimport ("fmt""time")func main() {startedAt := time.Now()defer fmt.Println(time.Since(startedAt))time.Sleep(time.Second) //休眠一秒}
结果是:
D:\workspace\go\src\test>go run main.go
0s
运行结果并不符合我们的预期,这个现象背后的原因是什么呢?经过分析,我们会发现调用 defer 关键字会立刻拷贝函数中引用的外部参数,所以 time.Since(startedAt) 的结果不是在 main 函数退出之前计算的,而是在 defer 关键字调用时计算的【defer入栈的时候】,最终导致上述代码输出 0s
我们再来看个简单例子来说明上述解释:
package mainimport ("fmt")func main() {i := 1defer fmt.Println(test(i))i = 100}func test(i int) int {i = i + 1return i} D:\workspace\go\src\test>go run main.go2
当代码运行到defer fmt.Println(test(i))的时候,会把defer右边最外层函数的参数计算完毕,并传递进函数里,但不会执行函数体的代码直到包裹defer的函数返回。我们先看会把defer右边最外层函数的参数计算完毕,并传递进函数里这句话,对应例子就是先把test(i)算出来,此时i=1,计算test(1)得2,然后fmt.Println(2)入栈,等到最后程序运行完了再运行defer结果就是2(但不会执行函数体的代码直到包裹defer的函数返回)。
我们再来看一个例子与匿名函数结合:
package mainimport ("fmt")func main() {i := 1defer func() {fmt.Println(test(i))}()i = 100}func test(i int) int {i = i + 1return i}
结果:
D:\workspace\go\src\test>go run main.go
101
使用匿名函数,结果是101,相当于i给到test方法的是100,那为什么呢?还是那句话:但不会执行函数体的代码直到包裹defer的函数返回
也就是说他会把整个{ fmt.Println(test(i)) }()函数体入栈,等到最后程序运行完了再运行defer,此时的i是100,运行test后就是101了。
所以你要解决第一个打印为0s的问题,你就可以使用匿名函数来解决,如下:
package mainimport ("fmt""time")func main() {startedAt := time.Now()defer func() {fmt.Println(time.Since(startedAt))}()time.Sleep(time.Second) //休眠一秒}
结果:
D:\workspace\go\src\test>go run main.go
1.0152825s
看完了这篇文章,相信你对“Golang中defer预计算参数怎么用”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网GO频道,感谢各位的阅读!
--结束END--
本文标题: Golang中defer预计算参数怎么用
本文链接: https://lsjlt.com/news/325727.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-04-05
2024-04-05
2024-04-05
2024-04-04
2024-04-05
2024-04-05
2024-04-05
2024-04-05
2024-04-04
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0