defer vs return

defer 看起来与try...catch 类似,其实有许多不为人知的小技巧

defer

官方行文defer先进后出,对return进行一些扫尾工作。这意味着使用该函数在返回值之前,defer函数内是可以访问使用defer的函数内任意变量。那么问题来了,在defer函数内对所在函数变量进行修改,会影响返回的结果吗?

码说

示例展示了两个使用defer的函数。用匿名返回类型,与具名返回类型函数,猜猜结果有无变化?

 package main

 import "fmt"

 func main() {
     fmt.Println("tstring return: ", tstring())
     fmt.Println("tstring1 return: ", tstring1())
 }

 func tstring() string {
     s := "a_"
     defer func() {
         s = s + "a"
         fmt.Println("defer: ", s)
     }()
     return s
 }

 func tstring1() (s string) {
     defer func() {
         s = s + "b"
         fmt.Println("defer1: ", s)
     }()
     return s
 }

测试

代码验证

 vagrant@homestead  go run test.go
defer:  a_a
tstring return:  a_
defer1:  b
tstring1 return:  b

结论

是不是很诡异?具名返回值类型时,结合defer可以修改return返回值,而匿名则不会。

细细思之,这种安排也合情合理,谁还会将一次性手纸重复利用?
匿名变量顾名思义,用过即丢,不会再理了。具名,为什么要有名字,不就是为了复用。
既然是复用,再次用之怎能不可改变?否则安排就没意义了

拓展

想想如果返回类型是指针类型,有名与无名返回类型是否有区别?

pardon110
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!