学习go的反射对于理解go的底层实现以及接口机制有着非常重要的价值;本篇文章从一个源程序来体验一下go反射的两个核心函数TypeOf 和ValueOf的使用方法,特别体验下怎么根据type构造type实例的办法。
package main import ( "fmt" "reflect" ) type Speaker interface { Speak()string Set(string) } type Teacher struct { Name string } func (this *Teacher) Speak() string { return this.Name } func (this *Teacher) Set(name string) { this.Name = name } func TestRef(s Speaker)(t reflect.Type){ reflectVal := reflect.ValueOf(s) //t = reflect.Indirect(reflectVal).Type() t = reflectVal.Elem().Type() fmt.Printf("reflect.ValueOf(%v).Elem().Type()=%v\n",s,t) return } func TestRef2(s Speaker)(t reflect.Type){ //t = reflect.TypeOf(s).Elem() //fmt.Printf("reflect.TypeOf(%v).Elem()=%v\n",s,t) t = reflect.TypeOf(s) fmt.Printf("reflect.TypeOf(%v)=%v\n",s,t) return } func TestRef3(s *Teacher)(t reflect.Type){ t = reflect.TypeOf(s).Elem() fmt.Printf("reflect.TypeOf(%v).Elem()=%v\n",s,t) return } func main(){ te := &Teacher{ Name:"newyear", } fmt.Printf("source=%v\n",te) fmt.Printf("\n") var tea Speaker = te t1 := TestRef(tea) //默认是创建一个零值实例,string 就是"" if m, ok := reflect.New(t1).Interface().(Speaker); ok { fmt.Printf("reflect.New(%v).Interface().(Speaker)=%v\n",t1, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) m.Set("2014") fmt.Printf("reflect.New(%v).Interface().(Speaker)=%v\n",t1, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") t2 := TestRef2(tea) //if m, ok := reflect.New(t2).Interface().(Speaker); ok { if m, ok := reflect.New(t2.Elem()).Interface().(Speaker); ok { fmt.Printf("reflect.New(%v.Elem()).Interface().(Speaker)=%v\n",t2, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) m.Set("2015") fmt.Printf("reflect.New(%v.Elem()).Interface().(Speaker)=%v\n",t2, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") t3 := TestRef3(te) if m, ok := reflect.New(t3).Interface().(Speaker); ok { fmt.Printf("reflect.New(%v).Interface().(Speaker)=%v\n", t3, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) m.Set("2016") fmt.Printf("reflect.New(%v).Interface().(Speaker)=%v\n", t3, m) fmt.Printf("se.Speak()=%v\n",m.Speak()) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") fmt.Printf("reflect.TypeOf(tea)=%v\n",reflect.TypeOf(tea)) fmt.Printf("reflect.TypeOf(tea).Elem()=%v\n",reflect.TypeOf(tea).Elem()) fmt.Printf("reflect.ValueOf(tea)=%v\n",reflect.ValueOf(tea)) fmt.Printf("reflect.ValueOf(tea).Elem()=%v\n",reflect.ValueOf(tea).Elem()) fmt.Printf("\n") if se, ok := reflect.ValueOf(tea).Interface().(Speaker); ok { //if se, ok := reflect.ValueOf(te).Interface().(Speaker); ok { fmt.Printf("reflect.ValueOf(%v).Interface().(Speaker)=%v\n",tea, se) fmt.Printf("se.Speak()=%v\n",se.Speak()) se.Set("2017") fmt.Printf("reflect.ValueOf(%v).Interface().(Speaker)=%v\n",tea, se) fmt.Printf("se.Speak()=%v\n",se.Speak()) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") //if se, ok := reflect.New(reflect.TypeOf(te).Elem()).Interface().(Speaker); ok { if se, ok := reflect.New(reflect.TypeOf(tea).Elem()).Interface().(Speaker); ok { fmt.Printf("reflect.New(reflect.TypeOf(%v).Elem()).Interface().(Speaker)=%v\n",tea,se) fmt.Printf("se.Speak()=%v\n",se.Speak()) se.Set("2018") fmt.Printf("reflect.New(reflect.TypeOf(%v).Elem()).Interface().(Speaker)=%v\n",tea,se) fmt.Printf("se.Speak()=%v\n",se.Speak()) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") if se, ok := reflect.New(reflect.TypeOf(te).Elem()).Interface().(Speaker); ok { fmt.Printf("reflect.New(reflect.TypeOf(%v).Elem()).Interface().(Speaker)=%v\n",te,se) fmt.Printf("se.Speak()=%v\n",se.Speak()) se.Set("2019") fmt.Printf("se.Speak()=%v\n",se.Speak()) fmt.Printf("reflect.New(reflect.TypeOf(%v).Elem()).Interface().(Speaker)=%v\n",te,se) } fmt.Printf("Source Instance te=%v\n",te) fmt.Printf("\n") }
有疑问加站长微信联系(非本文作者)