blob: c4a312464bcf4e130143941e67421b1a1615fa94 [file] [log] [blame]
Russ Cox0b477ef2012-02-16 23:48:57 -05001// run
Russ Cox0f4f2a62009-02-06 13:46:56 -08002
3// Copyright 2009 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
Rob Pikefc0dc042012-02-19 13:19:43 +11007// Test the behavior of closures.
8
Russ Cox0f4f2a62009-02-06 13:46:56 -08009package main
10
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +010011import "runtime"
12
Rob Pike325cf8e2010-03-24 16:46:53 -070013var c = make(chan int)
Russ Cox0f4f2a62009-02-06 13:46:56 -080014
15func check(a []int) {
16 for i := 0; i < len(a); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070017 n := <-c
Russ Cox0f4f2a62009-02-06 13:46:56 -080018 if n != a[i] {
Rob Pike325cf8e2010-03-24 16:46:53 -070019 println("want", a[i], "got", n, "at", i)
20 panic("fail")
Russ Cox0f4f2a62009-02-06 13:46:56 -080021 }
22 }
23}
24
25func f() {
Rob Pike325cf8e2010-03-24 16:46:53 -070026 var i, j int
Russ Cox0f4f2a62009-02-06 13:46:56 -080027
Rob Pike325cf8e2010-03-24 16:46:53 -070028 i = 1
29 j = 2
Russ Cox0f4f2a62009-02-06 13:46:56 -080030 f := func() {
Rob Pike325cf8e2010-03-24 16:46:53 -070031 c <- i
32 i = 4
Russ Cox0f4f2a62009-02-06 13:46:56 -080033 g := func() {
Rob Pike325cf8e2010-03-24 16:46:53 -070034 c <- i
35 c <- j
36 }
37 g()
38 c <- i
39 }
40 j = 5
41 f()
Russ Cox0f4f2a62009-02-06 13:46:56 -080042}
43
44// Accumulator generator
Rob Pike325cf8e2010-03-24 16:46:53 -070045func accum(n int) func(int) int {
Russ Cox0f4f2a62009-02-06 13:46:56 -080046 return func(i int) int {
Rob Pike325cf8e2010-03-24 16:46:53 -070047 n += i
48 return n
Russ Cox0f4f2a62009-02-06 13:46:56 -080049 }
50}
51
52func g(a, b func(int) int) {
Rob Pike325cf8e2010-03-24 16:46:53 -070053 c <- a(2)
54 c <- b(3)
55 c <- a(4)
56 c <- b(5)
Russ Cox0f4f2a62009-02-06 13:46:56 -080057}
58
59func h() {
Rob Pike325cf8e2010-03-24 16:46:53 -070060 var x8 byte = 100
61 var x64 int64 = 200
Russ Cox0f4f2a62009-02-06 13:46:56 -080062
Rob Pike325cf8e2010-03-24 16:46:53 -070063 c <- int(x8)
64 c <- int(x64)
Russ Cox0f4f2a62009-02-06 13:46:56 -080065 f := func(z int) {
66 g := func() {
Rob Pike325cf8e2010-03-24 16:46:53 -070067 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)
Russ Cox0f4f2a62009-02-06 13:46:56 -080079}
80
Rob Pike325cf8e2010-03-24 16:46:53 -070081func newfunc() func(int) int { return func(x int) int { return x } }
Russ Cox9346c6d2009-07-28 20:01:00 -070082
Russ Cox0f4f2a62009-02-06 13:46:56 -080083func main() {
Dmitriy Vyukov91e56e62012-07-01 21:59:50 +040084 runtime.GOMAXPROCS(1)
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +010085 var fail bool
86
Rob Pike325cf8e2010-03-24 16:46:53 -070087 go f()
88 check([]int{1, 4, 5, 4})
Russ Cox0f4f2a62009-02-06 13:46:56 -080089
Rob Pike325cf8e2010-03-24 16:46:53 -070090 a := accum(0)
91 b := accum(1)
92 go g(a, b)
93 check([]int{2, 4, 6, 9})
Russ Cox0f4f2a62009-02-06 13:46:56 -080094
Rob Pike325cf8e2010-03-24 16:46:53 -070095 go h()
96 check([]int{100, 200, 101, 201, 500, 101, 201, 500})
Russ Cox9346c6d2009-07-28 20:01:00 -070097
Rémy Oudompheng842c9062012-02-06 19:16:26 +010098 memstats := new(runtime.MemStats)
99 runtime.ReadMemStats(memstats)
100 n0 := memstats.Mallocs
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +0100101
Rob Pike325cf8e2010-03-24 16:46:53 -0700102 x, y := newfunc(), newfunc()
Russ Cox9346c6d2009-07-28 20:01:00 -0700103 if x(1) != 1 || y(2) != 2 {
Rob Pike325cf8e2010-03-24 16:46:53 -0700104 println("newfunc returned broken funcs")
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +0100105 fail = true
106 }
107
Rémy Oudompheng842c9062012-02-06 19:16:26 +0100108 runtime.ReadMemStats(memstats)
109 if n0 != memstats.Mallocs {
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +0100110 println("newfunc allocated unexpectedly")
111 fail = true
Russ Cox9346c6d2009-07-28 20:01:00 -0700112 }
Russ Cox1b31c372010-12-13 16:51:19 -0500113
114 ff(1)
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +0100115
116 if fail {
Rémy Oudompheng842c9062012-02-06 19:16:26 +0100117 panic("fail")
Luuk van Dijk25cf9bd2012-01-10 21:47:22 +0100118 }
Russ Cox1b31c372010-12-13 16:51:19 -0500119}
120
121func ff(x int) {
122 call(func() {
123 _ = x
124 })
125}
126
127func call(func()) {
Russ Cox0f4f2a62009-02-06 13:46:56 -0800128}