go中defer的理解--defer、return、返回值之间执行顺序
defer可以读取有名返回值func c() (i int) { defer func() { i++ }() return 1 } 输出结果是2. 在开头的时候,我们知道defer是在return调用之后才执行的。 这里需要明确的是defer代码块的作用域仍然在函数之内,结合上面的函数也就是说,defer的作用域仍然在c函数之内。因此defer仍然可以读取c函数内的变量(如果无法读取函数内变量,那又如何进行变量清除呢....)。 当执行return 1 之后,i的值就是1. 此时此刻,defer代码块开始执行,对i进行自增操作。 因此输出2. A. 无名返回值的情况 package main import ( "fmt" ) func main() { fmt.Println(return:",a()) // 打印结果为 return: 0 } func a() { var i defer func() { i++ fmt.Println(defer2: 打印结果为 defer: 2 }() defer func() { i++defer1: 打印结果为 defer: 1 }() return i } B. 有名返回值的情况 打印结果为 return: 2 } func b() (i ) { defer func() { i++return i 或者直接 return 效果相同 } 先来假设出结论,帮助大家理解
如何解释两种结果的不同: 上面两段代码的返回结果之所以不同,其实从上面第2条结论很好理解。? C. 下面我们再来看第三个例子,验证上面的结论: c return: 打印结果为 c return: 2 } func c() *c defer2: 打印结果为 c defer: 2 c defer1: 打印结果为 c defer: 1 return &i } 虽然 c()*int 的返回值没有被提前声明,但是由于 c()*int 的返回值是指针变量,那么在return将变量 i 的地址赋给返回值后,defer再次修改了 i 在内存中的实际值,因此函数退出时返回值虽然依旧是原来的指针地址,但是其指向的内存实际值已经被成功修改了。? 转载:https://my.oschina.net/henrylee2cn/blog/505535?utm_campaign=studygolang.com&utm_medium=studygolang.com&utm_source=studygolang.com (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |