1package main 2 3import ( 4 "fmt" 5 "reflect" 6 _ "reflect" 7 "unsafe" 8) 9 10type Pair struct{ A, B int } 11 12func pair(a, b int) Pair { var p Pair; p.A = a; p.B = b; return p } 13 14type Triple struct { 15 Pair 16 C int 17} 18 19func (p Pair) First() int { 20 return p.A 21} 22 23func (p Pair) Last() int { 24 return p.B 25} 26 27func (t Triple) Last() int { 28 return t.C 29} 30 31func embedded_field() { 32 printChars() 33 inspectTriple() 34} 35 36func printChars() { 37 for i := 128; i <= 255; i++ { 38 fmt.Printf("%x %c\n", i, i) 39 } 40} 41 42func inspectTriple() { 43 t := Triple{Pair{1, 2}, 3} 44 inspect("declared: ", t.Pair.First) 45 inspect("declared2: ", t.Pair.First) 46 inspect("wrapped: ", t.First) 47 inspect("wrapped2: ", t.First) 48 inspect("declared (reflect):", reflect.ValueOf(t.Pair).MethodByName("First").Interface().(func() int)) 49 inspect("declared2 (reflect):", reflect.ValueOf(t.Pair).MethodByName("First").Interface().(func() int)) 50 inspect("wrapped (reflect):", reflect.ValueOf(t).MethodByName("First").Interface().(func() int)) 51 inspect("wrapped2 (reflect):", reflect.ValueOf(t).MethodByName("First").Interface().(func() int)) 52 fmt.Println() 53 inspect("declared: ", t.Pair.Last) 54 inspect("declared2: ", t.Pair.Last) 55 inspect("overridden: ", t.Last) 56 inspect("overridden2: ", t.Last) 57 inspect("declared (reflect):", reflect.ValueOf(t.Pair).MethodByName("Last").Interface().(func() int)) 58 inspect("declared2 (reflect):", reflect.ValueOf(t.Pair).MethodByName("Last").Interface().(func() int)) 59 inspect("overridden (reflect):", reflect.ValueOf(t).MethodByName("Last").Interface().(func() int)) 60 inspect("overridden2 (reflect):", reflect.ValueOf(t).MethodByName("Last").Interface().(func() int)) 61 fmt.Println() 62 /* 63 inspectMethod1(t, "First") 64 inspectMethod1(t.Pair, "First") 65 inspectMethod1(t, "Last") 66 inspectMethod1(t.Pair, "Last") 67 */ 68} 69 70func inspect(name string, x func() int) { 71 u := *(**uintptr)(unsafe.Pointer(&x)) 72 u4 := *(**[16]uintptr)(unsafe.Pointer(&x)) 73 fmt.Printf("%s %#v %#v %#v\n", name, x, u, *u4) 74} 75 76type UnsafeValue struct { 77 typ *uintptr 78 ptr unsafe.Pointer 79 flag uintptr 80} 81type UnsafeInterface struct { 82 typ *uintptr 83 ptr unsafe.Pointer 84} 85 86func inspectMethod(x interface{}, y interface{}, name string) { 87 mtd1 := reflect.ValueOf(x).MethodByName(name).Interface() 88 mtd2 := reflect.ValueOf(y).MethodByName(name).Interface() 89 90 inspectMethod1(mtd1, name) 91 inspectMethod1(mtd2, name) 92} 93 94func inspectMethod1(mtd interface{}, name string) { 95 fmt.Printf("%s:\t%#v\n", name, mtd) 96 uf := *(*UnsafeInterface)(unsafe.Pointer(&mtd)) 97 fmt.Printf("%s:\tInterface = %#v\n", name, uf) 98 fptr := (**uintptr)(uf.ptr) 99 fmt.Printf("%s:\tInterface.ptr = %#v %#v\n", name, fptr, *fptr) 100} 101 102func inspectMethod2(x interface{}, name string) { 103 t := reflect.TypeOf(x) 104 mtd, _ := t.MethodByName(name) 105 fmt.Printf("%s:\t%v\n", name, mtd) 106 var f reflect.Value = mtd.Func 107 uf := *(*UnsafeValue)(unsafe.Pointer(&f)) 108 fmt.Printf("%s:\tFunc = %#v\n", name, uf) 109 fptr := (**uintptr)(uf.ptr) 110 fmt.Printf("%s:\tFunc.ptr = %#v %#v %#v\n", name, fptr, *fptr, **fptr) 111} 112