结论:return 与 defer 的执行顺序是先执行 return,后执行 defer 函数返回值定义分为两种,一种是匿名返回值,另一种是具名返回值
匿名返回值与defer
func Sum(a, b int) int {
var result int
defer func() {
result = -1
}()
result = a + b
return result
}
执行 Sum(1, 2) 后打印的返回值是3,defer并没有影响到返回值。原因:在匿名返回值的函数中,执行return 时会生成一个临时变量,将 return 的结果赋值给临时变量,然后再执行 defer,defer 修改的是 result 变量,而函数返回的是临时变量,所以并不会影响到返回值
具名返回值与defer
func Sum(a, b int) (result int) {
defer func() {
result = -1
}()
result = a + b
return result
}
我们将匿名返回值例子中 Sum 函数的返回值定义修改为具名返回值,执行 Sum(1, 2) 后打印的返回值是-1,此时 defer 却能正常修改返回值。原因:具名返回值函数会在函数执行前将具名变量(示例中的result)定义好,并且函数最终返回的就是具名变量。因此,defer 修改的是 result 具名变量,返回的变量也是具名变量 result,所以函数返回的结果就是 defer 修改后的值。(注意:return result 会将 result 变量赋值给 result 变量,然后再执行 defer)
思考以下例子的返回值 Sum(1, 2), 3 or 9?
func Sum(a, b int) (result int) {
result = a + b
return 9
}
结果是9,执行 return 语句时将9赋值给了具名返回值变量 result。