|  | // run | 
|  |  | 
|  | // 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. | 
|  |  | 
|  | // Test embedded fields of structs, including methods. | 
|  |  | 
|  | package main | 
|  |  | 
|  |  | 
|  | type I interface { | 
|  | test1() int | 
|  | test2() int | 
|  | test3() int | 
|  | test4() int | 
|  | test5() int | 
|  | test6() int | 
|  | test7() int | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type SubpSubp struct { | 
|  | a7 int | 
|  | a  int | 
|  | } | 
|  |  | 
|  | func (p *SubpSubp) test7() int { | 
|  | if p.a != p.a7 { | 
|  | println("SubpSubp", p, p.a7) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  | func (p *SubpSubp) testx() { println("SubpSubp", p, p.a7) } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type SubpSub struct { | 
|  | a6 int | 
|  | SubpSubp | 
|  | a int | 
|  | } | 
|  |  | 
|  | func (p *SubpSub) test6() int { | 
|  | if p.a != p.a6 { | 
|  | println("SubpSub", p, p.a6) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  | func (p *SubpSub) testx() { println("SubpSub", p, p.a6) } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type SubSubp struct { | 
|  | a5 int | 
|  | a  int | 
|  | } | 
|  |  | 
|  | func (p *SubSubp) test5() int { | 
|  | if p.a != p.a5 { | 
|  | println("SubpSub", p, p.a5) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type SubSub struct { | 
|  | a4 int | 
|  | a  int | 
|  | } | 
|  |  | 
|  | func (p *SubSub) test4() int { | 
|  | if p.a != p.a4 { | 
|  | println("SubpSub", p, p.a4) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type Subp struct { | 
|  | a3 int | 
|  | *SubpSubp | 
|  | SubpSub | 
|  | a int | 
|  | } | 
|  |  | 
|  | func (p *Subp) test3() int { | 
|  | if p.a != p.a3 { | 
|  | println("SubpSub", p, p.a3) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type Sub struct { | 
|  | a2 int | 
|  | *SubSubp | 
|  | SubSub | 
|  | a int | 
|  | } | 
|  |  | 
|  | func (p *Sub) test2() int { | 
|  | if p.a != p.a2 { | 
|  | println("SubpSub", p, p.a2) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | type S struct { | 
|  | a1 int | 
|  | Sub | 
|  | *Subp | 
|  | a int | 
|  | } | 
|  |  | 
|  | func (p *S) test1() int { | 
|  | if p.a != p.a1 { | 
|  | println("SubpSub", p, p.a1) | 
|  | panic("fail") | 
|  | } | 
|  | return p.a | 
|  | } | 
|  |  | 
|  | /****** | 
|  | ****** | 
|  | ******/ | 
|  |  | 
|  | func main() { | 
|  | var i I | 
|  | var s *S | 
|  |  | 
|  | // allocate | 
|  | s = new(S) | 
|  | s.Subp = new(Subp) | 
|  | s.Sub.SubSubp = new(SubSubp) | 
|  | s.Subp.SubpSubp = new(SubpSubp) | 
|  |  | 
|  | // explicit assignment | 
|  | s.a = 1 | 
|  | s.Sub.a = 2 | 
|  | s.Subp.a = 3 | 
|  | s.Sub.SubSub.a = 4 | 
|  | s.Sub.SubSubp.a = 5 | 
|  | s.Subp.SubpSub.a = 6 | 
|  | s.Subp.SubpSubp.a = 7 | 
|  |  | 
|  | // embedded (unique) assignment | 
|  | s.a1 = 1 | 
|  | s.a2 = 2 | 
|  | s.a3 = 3 | 
|  | s.a4 = 4 | 
|  | s.a5 = 5 | 
|  | s.a6 = 6 | 
|  | s.a7 = 7 | 
|  |  | 
|  | // unique calls with explicit & | 
|  | if s.test1() != 1 { | 
|  | println("t1", 1) | 
|  | panic("fail") | 
|  | } | 
|  | if (&s.Sub).test2() != 2 { | 
|  | println("t1", 2) | 
|  | panic("fail") | 
|  | } | 
|  | if s.Subp.test3() != 3 { | 
|  | println("t1", 3) | 
|  | panic("fail") | 
|  | } | 
|  | if (&s.Sub.SubSub).test4() != 4 { | 
|  | println("t1", 4) | 
|  | panic("fail") | 
|  | } | 
|  | if s.Sub.SubSubp.test5() != 5 { | 
|  | println("t1", 5) | 
|  | panic("fail") | 
|  | } | 
|  | if (&s.Subp.SubpSub).test6() != 6 { | 
|  | println("t1", 6) | 
|  | panic("fail") | 
|  | } | 
|  | if s.Subp.SubpSubp.test7() != 7 { | 
|  | println("t1", 7) | 
|  | panic("fail") | 
|  | } | 
|  |  | 
|  | // automatic & | 
|  | if s.Sub.test2() != 2 { | 
|  | println("t2", 2) | 
|  | panic("fail") | 
|  | } | 
|  | if s.Sub.SubSub.test4() != 4 { | 
|  | println("t2", 4) | 
|  | panic("fail") | 
|  | } | 
|  | if s.Subp.SubpSub.test6() != 6 { | 
|  | println("t2", 6) | 
|  | panic("fail") | 
|  | } | 
|  |  | 
|  | // embedded calls | 
|  | if s.test1() != s.a1 { | 
|  | println("t3", 1) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test2() != s.a2 { | 
|  | println("t3", 2) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test3() != s.a3 { | 
|  | println("t3", 3) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test4() != s.a4 { | 
|  | println("t3", 4) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test5() != s.a5 { | 
|  | println("t3", 5) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test6() != s.a6 { | 
|  | println("t3", 6) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test7() != s.a7 { | 
|  | println("t3", 7) | 
|  | panic("fail") | 
|  | } | 
|  |  | 
|  | // run it thru an interface | 
|  | i = s | 
|  | s = i.(*S) | 
|  |  | 
|  | // same as t3 | 
|  | if s.test1() != s.a1 { | 
|  | println("t4", 1) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test2() != s.a2 { | 
|  | println("t4", 2) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test3() != s.a3 { | 
|  | println("t4", 3) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test4() != s.a4 { | 
|  | println("t4", 4) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test5() != s.a5 { | 
|  | println("t4", 5) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test6() != s.a6 { | 
|  | println("t4", 6) | 
|  | panic("fail") | 
|  | } | 
|  | if s.test7() != s.a7 { | 
|  | println("t4", 7) | 
|  | panic("fail") | 
|  | } | 
|  |  | 
|  | // call interface | 
|  | if i.test1() != s.test1() { | 
|  | println("t5", 1) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test2() != s.test2() { | 
|  | println("t5", 2) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test3() != s.test3() { | 
|  | println("t5", 3) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test4() != s.test4() { | 
|  | println("t5", 4) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test5() != s.test5() { | 
|  | println("t5", 5) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test6() != s.test6() { | 
|  | println("t5", 6) | 
|  | panic("fail") | 
|  | } | 
|  | if i.test7() != s.test7() { | 
|  | println("t5", 7) | 
|  | panic("fail") | 
|  | } | 
|  | } |