--- /dev/null
+package main
+
+import (
+ "fmt"
+ "reflect"
+ "example/hello"
+)
+
+type T struct {
+ A int
+ B string
+}
+
+func reflectStruct(v interface{}) {
+ fmt.Println("====")
+ s := reflect.ValueOf(v)
+ if s.Kind() == reflect.Pointer {
+ fmt.Println("get pointer", s.Type())
+ s = s.Elem()
+ }
+ typeOfT := s.Type()
+ fmt.Println("type:", typeOfT)
+ for i := 0; i < s.NumField(); i++ {
+ f := s.Field(i)
+ if typeOfT.Field(i).IsExported() {
+ fmt.Printf("%d: %s %s = %v (CanSet = %v)\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface(), f.CanSet())
+ } else {
+ fmt.Printf("%d: %s %s = unexported (CanSet = %v, CanAddr = %v)\n", i, typeOfT.Field(i).Name, f.Type(), f.CanSet(), f.CanAddr())
+ if f.CanAddr() {
+ fmt.Println("CanSet Addr", f.Addr().CanSet(), f.Addr().Elem().CanSet())
+ if f.Type().Name() == "int" {
+ fptr := (*int)(f.Addr().UnsafePointer())
+ fmt.Printf("... unsafe value: %v \n", *fptr)
+ *fptr = 77
+ fmt.Printf("... unsafe set: %v \n", *fptr)
+ } else if f.Type().Name() == "string" {
+ fptr := (*string)(f.Addr().UnsafePointer())
+ fmt.Printf("... unsafe value: %v \n", *fptr)
+ *fptr = "brrr"
+ fmt.Printf("... unsafe set: %v \n", *fptr)
+ }
+ }
+ }
+ }
+}
+
+func main() {
+ var x1 float64 = 3.4
+ fmt.Println("type:", reflect.TypeOf(x1))
+ v1 := reflect.ValueOf(x1)
+ fmt.Println("value:", v1.String())
+ fmt.Println("type:", v1.Type())
+ fmt.Println("kind is float64:", v1.Kind() == reflect.Float64)
+ fmt.Println("value:", v1.Float())
+
+ fmt.Println("====")
+ var x2 uint8 = 'x'
+ v2 := reflect.ValueOf(x2)
+ fmt.Println("type:", v2.Type()) // uint8.
+ fmt.Println("kind is uint8: ", v2.Kind() == reflect.Uint8) // true.
+ fmt.Println("value:", v2.Uint())
+ x2 = uint8(v2.Uint()) // v2.Uint returns a uint64.
+ fmt.Println("x2:", x2)
+
+ fmt.Println("====")
+ type MyInt int
+ var x3 MyInt = 7
+ v3 := reflect.ValueOf(x3)
+ fmt.Println("type:", v3.Type())
+ fmt.Println("kind is int: ", v3.Kind() == reflect.Int) // true.
+ fmt.Println("value:", v3.Int())
+
+ fmt.Println("====")
+ y1 := v1.Interface().(float64) // y will have type float64.
+ fmt.Printf("%v %T\n", y1, y1)
+ fmt.Printf("%v %T\n", v1.Interface(), v1.Interface())
+ fmt.Printf("value is %7.1e\n", v1.Interface())
+
+ fmt.Println("====")
+ var x4 float64 = 3.4
+ v4 := reflect.ValueOf(x4)
+ //v4.SetFloat(7.1) // Error: will panic.
+
+ fmt.Println("settability of v4:", v4.CanSet())
+
+ p4 := reflect.ValueOf(&x4) // Note: take the address of x.
+ fmt.Println("type of p4:", p4.Type())
+ fmt.Println("settability of p4:", p4.CanSet())
+ fmt.Println("settability of *p4:", p4.Elem().CanSet())
+ p4.Elem().SetFloat(7.1)
+ fmt.Println("x4:", x4)
+
+ fmt.Println("====")
+ t := T{23, "skidoo"}
+ s := reflect.ValueOf(&t).Elem()
+ typeOfT := s.Type()
+ fmt.Println("type:", typeOfT)
+ for i := 0; i < s.NumField(); i++ {
+ f := s.Field(i)
+ fmt.Printf("%d: %s %s = %v\n", i,
+ typeOfT.Field(i).Name, f.Type(), f.Interface())
+ }
+ s.Field(0).SetInt(77)
+ s.Field(1).SetString("Sunset Strip")
+ fmt.Println("t is now", t)
+
+ fmt.Println()
+ h1 := hello.H1{"H1", 11}
+ reflectStruct(h1)
+ reflectStruct(&h1)
+ fmt.Println("got:", h1)
+
+ h2 := hello.NewH2("H2")
+ reflectStruct(h2)
+ reflectStruct(&h2)
+ fmt.Println("got:", h2)
+
+ h3 := hello.NewH3("H3", 11)
+ reflectStruct(h3)
+ reflectStruct(&h3)
+ fmt.Println("got:", h3)
+
+}