首页 > 其他分享 >golang的defer使用一

golang的defer使用一

时间:2022-12-05 21:03:03浏览次数:39  
标签:defer return fmt Printf golang func 使用 Println

先来看例子:

例子1:

package main

import "fmt"

func refertest() int {
var i int
fmt.Printf("在没有调用defer之前。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
defer func() {
i++
fmt.Printf("第一个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()
defer func() {
i++
fmt.Printf("第二个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()

return i
}

func main() {
fmt.Println("main", refertest())
}

golang的defer使用一_执行顺序

从这个例子看到i变量的地址一样。defer func修改的i跟返回i变量都是同一个变量,为什么return i 是0?

例子2:我们取消defer,再来测试一下。

package main

import "fmt"

func refertest() int {
var i int
fmt.Printf("在没有调用defer之前。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
//取消defer
func() {
i++
fmt.Printf("第一个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()
//取消defer
func() {
i++
fmt.Printf("第二个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()

return i
}

func main() {
fmt.Println("main", refertest())
}

golang的defer使用一_函数返回_02

终于看到i的返回是2了,导致上一个例子返回为0,主要原因是defer这个延迟执行导致。

例子​3,我们对程序进行修改一下

package main

import "fmt"

//在函数返回中加上(i int).
func refertest() (i int) {
//注释掉函数中对i变量的声明。
//var i int
fmt.Printf("在没有调用defer之前。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
defer func() {
i++
fmt.Printf("第一个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()
defer func() {
i++
fmt.Printf("第二个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()

return i
}

func main() {
fmt.Println("main", refertest())
}

golang的defer使用一_i++_03


例子1:返回i是0,我们得到一个结论defer执行顺序是:return负责将结果写入返回值中->接着defer开始执行一些收尾工作->最后函数携带当前返回值return退出。return的语句已经事先将返回值i给定义下来了,就是0。然后再等待defer执行对i++的修改。最后操作返回也不会影响return之前的赋值。

例子3:由于返回值提前声明了,所以在return的时候决定的返回值还是0,但是后面两个defer执行后进行了两次++,将i的值变为2,待defer执行完后,函数将i值进行了返回。

例子4,我们修改程序,把return i修改成return &i,返回i变量地址,不返回值。这个时候是可以返回2.

package main

import "fmt"

// func refertest() (i int)
func refertest() *int {
var i int
fmt.Printf("在没有调用defer之前。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
defer func() {
i++
fmt.Printf("第一个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()
defer func() {
i++
fmt.Printf("第二个defer。i的值为:%d,i的地址为:%p", i, &i)
fmt.Println()
}()

return &i
}

func main() {
//由于返回是指针变量。这里必须使用*来接收。
fmt.Println("main", *refertest())
}

golang的defer使用一_i++_04


标签:defer,return,fmt,Printf,golang,func,使用,Println
From: https://blog.51cto.com/wyf1226/5913274

相关文章