1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import "fmt"
func calc(index string, a, b int) int { ret := a + b fmt.Println(index, a, b, ret) return ret }
func main() { a := 1 b := 2 defer calc("1", a, calc("10", a, b))
a = 0 defer calc("2", a, calc("20", a, b))
b = 1 }
|
defer在定义的时候会计算好调用函数的参数,所以会优先输出10、20这两个参数,之后就是根据定义的顺序倒序执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| package main
import ( "fmt" )
func main() { fmt.Println(a()) // 1 0 1 fmt.Println(c()) // 2 fmt.Println(f0()) // 6 fmt.Println(f1()) // 1 fmt.Println(*f1p()) // 6 fmt.Println(f2()) // 1 fmt.Println(f3()) // 6 fmt.Println(f40()) // 1 fmt.Println(f4()) // 0 }
/** * 当defer被声明时,其参数就会被实时解析 * defer执行顺序为先进后出 */ func a() int { i := 0 defer fmt.Println(i) //输出0,因为i此时就是0 i++ defer fmt.Println(i) //输出1,因为i此时就是1 return i }
/** * 当执行return 1时,1先赋值给i.然后defer代码块开始执行,对i进行自增操作。 因此输出2 */ func c() (i int) { defer func() { i++ }() return 1 }
func f0() (t int) { t = 1 defer func() { t = t + 5 }() return t }
/** * t先赋值给r,然后执行defer,虽然t被改了,由于值传递返回值仍然是1 */ func f1() (r int) { t := 1 defer func() { t = t + 5 }() return t }
/** * t先赋值给r,然后执行defer,t被改了,由于传的是地址,返回值是6 */ func f1p() (r *int) { t := 1 defer func() { t = t + 5 }() return &t }
/** * r默认值是0,作为参数传入了defer不会修改r的值,1会赋值给r,返回值为1 */ func f2() (r int) { defer func(r int) { r = r + 5 }(r) return 1 }
/** * 1赋值给r,然后执行defer,此时r被修改为6,返回的r值为6 */ func f3() (r int) { defer func() { r = r + 5 }() return 1 }
/** * 0赋值给result,然后defer执行,result值自增变为1,返回值为1 */ func f40() (result int) { defer func() { result++ }() return 0 }
/** * return不写返回变量,声明的变量名字也会被返回0 */ func f4() (result int) { result = 0 return }
/** * 传入地址,i的值最终被改为了15,但是返回值是10 */ func f5(i *int) int { *i = 10 defer func() { *i = 15 }() return *i }
|