github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/test/closure2.go (about) 1 // run 2 3 // Copyright 2015 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 7 // Check that these do not use "by value" capturing, 8 // because changes are made to the value during the closure. 9 10 package main 11 12 func main() { 13 { 14 type X struct { 15 v int 16 } 17 var x X 18 func() { 19 x.v++ 20 }() 21 if x.v != 1 { 22 panic("x.v != 1") 23 } 24 25 type Y struct { 26 X 27 } 28 var y Y 29 func() { 30 y.v = 1 31 }() 32 if y.v != 1 { 33 panic("y.v != 1") 34 } 35 } 36 37 { 38 type Z struct { 39 a [3]byte 40 } 41 var z Z 42 func() { 43 i := 0 44 for z.a[1] = 1; i < 10; i++ { 45 } 46 }() 47 if z.a[1] != 1 { 48 panic("z.a[1] != 1") 49 } 50 } 51 52 { 53 w := 0 54 tmp := 0 55 f := func() { 56 if w != 1 { 57 panic("w != 1") 58 } 59 } 60 func() { 61 tmp = w // force capture of w, but do not write to it yet 62 _ = tmp 63 func() { 64 func() { 65 w++ // write in a nested closure 66 }() 67 }() 68 }() 69 f() 70 } 71 72 { 73 var g func() int 74 for i := range [2]int{} { 75 if i == 0 { 76 g = func() int { 77 return i // test that we capture by ref here, i is mutated on every interation 78 } 79 } 80 } 81 if g() != 1 { 82 panic("g() != 1") 83 } 84 } 85 86 { 87 var g func() int 88 q := 0 89 for range [2]int{} { 90 q++ 91 g = func() int { 92 return q // test that we capture by ref here 93 // q++ must on a different decldepth than q declaration 94 } 95 } 96 if g() != 2 { 97 panic("g() != 2") 98 } 99 } 100 101 { 102 var g func() int 103 var a [2]int 104 q := 0 105 for a[func() int { 106 q++ 107 return 0 108 }()] = range [2]int{} { 109 g = func() int { 110 return q // test that we capture by ref here 111 // q++ must on a different decldepth than q declaration 112 } 113 } 114 if g() != 2 { 115 panic("g() != 2") 116 } 117 } 118 }