go reflect TypeOf 与ValueOf

hittata · · 19262 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


学习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")

}



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:hittata

查看原文:go reflect TypeOf 与ValueOf

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

19262 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传