熟悉go语言的人都知道可以声明返回变量的变量名
例1:
func Test()(ret int){
ret=1002
return
}
如此 return后面不跟任何参数,也可以返回规定值。
本来以为这是一个没有什么用的功能,但是完全不是!
ok,让我们会想下普通的返回方式
例2:
func Test()(int){
return 1002
}
在设定返回值为1002,然后return触发defer语句,执行完成后(即便是defer抛出panic后被捕获),返回1002。
但是如果声明返回变量名之后,因为其作用域为整个函数。我们就有可能通过引用传值使用其他函数修改其返回值或者通过内部函数修改其返回值。
func main() { fmt.Println(Test0()) fmt.Println(Test1()) } func Test0()(ret string){ ChangeReturn(&ret) return } func Test1()(ret string){ func() { ret="test1" }() return } func ChangeReturn(ret *string){ *ret="test0" }
结果:
test0 test1
如此有什么意义呢?由于return会触发defer,函数抛出panic也会触发defer。所以我们可以在defer中,特别是通过recovery()函数捕获panic后,修改函数的返回值。
func main() { fmt.Println(Test0()) } func Test0()(ret string){ defer func() { err:=recover() if err!=nil{ ret=fmt.Sprint(err) } }() panic("this is a panic") return "normal" }
结果:
this is a panic