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 返回值,而匿名则不会。
细细思之,这种安排也合情合理,谁还会将一次性手纸重复利用?
匿名变量顾名思义,用过即丢,不会再理了。具名,为什么要有名字,不就是为了复用。
既然是复用,再次用之怎能不可改变?否则安排就没意义了
拓展#
想想如果返回类型是指针类型,有名与无名返回类型是否有区别?
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: