Source file
test/closure.go
1
2
3
4
5
6
7
8
9 package main
10
11 import "runtime"
12
13 var c = make(chan int)
14
15 func check(a []int) {
16 for i := 0; i < len(a); i++ {
17 n := <-c
18 if n != a[i] {
19 println("want", a[i], "got", n, "at", i)
20 panic("fail")
21 }
22 }
23 }
24
25 func f() {
26 var i, j int
27
28 i = 1
29 j = 2
30 f := func() {
31 c <- i
32 i = 4
33 g := func() {
34 c <- i
35 c <- j
36 }
37 g()
38 c <- i
39 }
40 j = 5
41 f()
42 }
43
44
45 func accum(n int) func(int) int {
46 return func(i int) int {
47 n += i
48 return n
49 }
50 }
51
52 func g(a, b func(int) int) {
53 c <- a(2)
54 c <- b(3)
55 c <- a(4)
56 c <- b(5)
57 }
58
59 func h() {
60 var x8 byte = 100
61 var x64 int64 = 200
62
63 c <- int(x8)
64 c <- int(x64)
65 f := func(z int) {
66 g := func() {
67 c <- int(x8)
68 c <- int(x64)
69 c <- z
70 }
71 g()
72 c <- int(x8)
73 c <- int(x64)
74 c <- int(z)
75 }
76 x8 = 101
77 x64 = 201
78 f(500)
79 }
80
81 func newfunc() func(int) int { return func(x int) int { return x } }
82
83 func main() {
84 runtime.GOMAXPROCS(1)
85 var fail bool
86
87 go f()
88 check([]int{1, 4, 5, 4})
89
90 a := accum(0)
91 b := accum(1)
92 go g(a, b)
93 check([]int{2, 4, 6, 9})
94
95 go h()
96 check([]int{100, 200, 101, 201, 500, 101, 201, 500})
97
98 memstats := new(runtime.MemStats)
99 runtime.ReadMemStats(memstats)
100 n0 := memstats.Mallocs
101
102 x, y := newfunc(), newfunc()
103 if x(1) != 1 || y(2) != 2 {
104 println("newfunc returned broken funcs")
105 fail = true
106 }
107
108 runtime.ReadMemStats(memstats)
109 if n0 != memstats.Mallocs {
110 println("newfunc allocated unexpectedly")
111 fail = true
112 }
113
114 ff(1)
115
116 if fail {
117 panic("fail")
118 }
119 }
120
121 func ff(x int) {
122 call(func() {
123 _ = x
124 })
125 }
126
127 func call(func()) {
128 }
129
View as plain text