// Tests of bound method closures. package main func assert(b bool) { if !b { panic("oops") } } type I int func (i I) add(x int) int { return int(i) + x } func valueReceiver() { var three I = 3 assert(three.add(5) == 8) var add3 func(int) int = three.add assert(add3(5) == 8) } type S struct{ x int } func (s *S) incr() { s.x++ } func (s *S) get() int { return s.x } func pointerReceiver() { ps := new(S) incr := ps.incr get := ps.get assert(get() == 0) incr() incr() incr() assert(get() == 3) } func addressibleValuePointerReceiver() { var s S incr := s.incr get := s.get assert(get() == 0) incr() incr() incr() assert(get() == 3) } type S2 struct { S } func promotedReceiver() { var s2 S2 incr := s2.incr get := s2.get assert(get() == 0) incr() incr() incr() assert(get() == 3) } func anonStruct() { var s struct{ S } incr := s.incr get := s.get assert(get() == 0) incr() incr() incr() assert(get() == 3) } func typeCheck() { var i interface{} i = (*S).incr _ = i.(func(*S)) // type assertion: receiver type prepended to params var s S i = s.incr _ = i.(func()) // type assertion: receiver type disappears } type errString string func (err errString) Error() string { return string(err) } // Regression test for a builder crash. func regress1(x error) func() string { return x.Error } func main() { valueReceiver() pointerReceiver() addressibleValuePointerReceiver() promotedReceiver() anonStruct() typeCheck() if e := regress1(errString("hi"))(); e != "hi" { panic(e) } }