| 
									
										
										
										
											2012-02-16 23:48:57 -05:00
										 |  |  | // run | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Copyright 2009 The Go Authors. All rights reserved. | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 13:19:43 +11:00
										 |  |  | // Test the behavior of closures. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | import "runtime" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | var c = make(chan int) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func check(a []int) { | 
					
						
							|  |  |  | 	for i := 0; i < len(a); i++ { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 		n := <-c | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 		if n != a[i] { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 			println("want", a[i], "got", n, "at", i) | 
					
						
							|  |  |  | 			panic("fail") | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func f() { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	var i, j int | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	i = 1 | 
					
						
							|  |  |  | 	j = 2 | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 	f := func() { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 		c <- i | 
					
						
							|  |  |  | 		i = 4 | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 		g := func() { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 			c <- i | 
					
						
							|  |  |  | 			c <- j | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		g() | 
					
						
							|  |  |  | 		c <- i | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	j = 5 | 
					
						
							|  |  |  | 	f() | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Accumulator generator | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | func accum(n int) func(int) int { | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 	return func(i int) int { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 		n += i | 
					
						
							|  |  |  | 		return n | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func g(a, b func(int) int) { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	c <- a(2) | 
					
						
							|  |  |  | 	c <- b(3) | 
					
						
							|  |  |  | 	c <- a(4) | 
					
						
							|  |  |  | 	c <- b(5) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func h() { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	var x8 byte = 100 | 
					
						
							|  |  |  | 	var x64 int64 = 200 | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	c <- int(x8) | 
					
						
							|  |  |  | 	c <- int(x64) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 	f := func(z int) { | 
					
						
							|  |  |  | 		g := func() { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 			c <- int(x8) | 
					
						
							|  |  |  | 			c <- int(x64) | 
					
						
							|  |  |  | 			c <- z | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		g() | 
					
						
							|  |  |  | 		c <- int(x8) | 
					
						
							|  |  |  | 		c <- int(x64) | 
					
						
							|  |  |  | 		c <- int(z) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	x8 = 101 | 
					
						
							|  |  |  | 	x64 = 201 | 
					
						
							|  |  |  | 	f(500) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | func newfunc() func(int) int { return func(x int) int { return x } } | 
					
						
							| 
									
										
										
										
											2009-07-28 20:01:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | func main() { | 
					
						
							| 
									
										
										
										
											2012-07-01 21:59:50 +04:00
										 |  |  | 	runtime.GOMAXPROCS(1) | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 	var fail bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	go f() | 
					
						
							|  |  |  | 	check([]int{1, 4, 5, 4}) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	a := accum(0) | 
					
						
							|  |  |  | 	b := accum(1) | 
					
						
							|  |  |  | 	go g(a, b) | 
					
						
							|  |  |  | 	check([]int{2, 4, 6, 9}) | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	go h() | 
					
						
							|  |  |  | 	check([]int{100, 200, 101, 201, 500, 101, 201, 500}) | 
					
						
							| 
									
										
										
										
											2009-07-28 20:01:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-06 19:16:26 +01:00
										 |  |  | 	memstats := new(runtime.MemStats) | 
					
						
							|  |  |  | 	runtime.ReadMemStats(memstats) | 
					
						
							|  |  |  | 	n0 := memstats.Mallocs | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 	x, y := newfunc(), newfunc() | 
					
						
							| 
									
										
										
										
											2009-07-28 20:01:00 -07:00
										 |  |  | 	if x(1) != 1 || y(2) != 2 { | 
					
						
							| 
									
										
										
										
											2010-03-24 16:46:53 -07:00
										 |  |  | 		println("newfunc returned broken funcs") | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 		fail = true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-06 19:16:26 +01:00
										 |  |  | 	runtime.ReadMemStats(memstats) | 
					
						
							|  |  |  | 	if n0 != memstats.Mallocs { | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 		println("newfunc allocated unexpectedly") | 
					
						
							|  |  |  | 		fail = true | 
					
						
							| 
									
										
										
										
											2009-07-28 20:01:00 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-13 16:51:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ff(1) | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if fail { | 
					
						
							| 
									
										
										
										
											2012-02-06 19:16:26 +01:00
										 |  |  | 		panic("fail") | 
					
						
							| 
									
										
										
										
											2012-01-10 21:47:22 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-12-13 16:51:19 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func ff(x int) { | 
					
						
							|  |  |  | 	call(func() { | 
					
						
							|  |  |  | 		_ = x | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func call(func()) { | 
					
						
							| 
									
										
										
										
											2009-02-06 13:46:56 -08:00
										 |  |  | } |