golang 基础——反射

1、反射普通变量

package main

import (
	"fmt"
	"reflect"
)


func test01() {
    
    
	var v float64 = 1.2

	// 方法1
	vo := reflect.ValueOf(v)
	fmt.Printf("Type=%T , Kind=%v ,val = %v\n", vo, vo.Kind(), vo.Float())

	// 方法2
	vo2 := vo.Interface()
	v2 := vo2.(float64)
	上面两行代码可以合并一行,如下
	//v2 :=  vo.Interface().(float64)
	

	fmt.Println("v2 =", v2)
}

// 使用反射修改变量 str的值
func test02() {
    
    
	var str string = "tom"
	fs := reflect.ValueOf(&str)
	fs.Elem().SetString("jack")
	fmt.Printf("str = %v\n", str)
}

type Student struct {
    
    
	Name string
	Age  int
}

func test03(b interface{
    
    }) {
    
    

	fs := reflect.ValueOf(b)
	itV := fs.Elem().Interface()
	stu2 := itV.(Student)

	fmt.Printf("stu2 name = %v\n", stu2.Name)
	//name2 := stu2.Name

	fs.Elem().FieldByName("Name").SetString("jack")
	//fs2 := reflect.ValueOf(&name2)
	//fs2.Elem().SetString("jack")

	//fmt.Printf("stu2 name = %v\n", stu2.Name)
}

func main() {
    
    
	stu := Student{
    
    
		Name: "zhangsan",
		Age:  30,
	}
	test03(&stu)
	fmt.Printf("main() stu2 name = %v\n", stu.Name)
}

2、反射结构体

package main

import (
	"fmt"
	"reflect"
)

type Monster struct {
    
    
	Name  string `json:"name"`
	Age   int    `json:"monster_name"`
	Score float32
	Sex   string
}

func (s Monster) Print() {
    
    
	fmt.Println("-----start--------")
	fmt.Println(s)
	fmt.Println("-----end--------")
}
func (s Monster) GetSum(n1, n2 int) int {
    
    
	return n1 + n2
}
func (s Monster) Set(name string, age int, score float32, sex string) {
    
    
	s.Name = name
	s.Age = age
	s.Score = score
	s.Sex = sex
}

func TestStruct(a interface{
    
    }) {
    
    
	typ := reflect.TypeOf(a)
	val := reflect.ValueOf(a)
	kd := val.Kind()
	if kd != reflect.Struct {
    
    
		fmt.Println("expect struct")
		return
	}

	num := val.NumField()
	fmt.Printf("struct has %d fields\n", num)
	for i := 0; i < num; i++ {
    
    
		fmt.Printf("Field %d 值: %v \n", i, val.Field(i))
		// 获取结构体的tag标签的值
		tagVal := typ.Field(i).Tag.Get("json")
		if tagVal != "" {
    
    
			fmt.Printf("Field %d tag: %v\n", i, tagVal)
		}
	}
	numOfMethod := val.NumMethod()
	fmt.Printf("struct has %d methods\n", numOfMethod)

	// 调用第2个方法,注意,方法是按照ASCI排序的
	val.Method(1).Call(nil)

	// 调用第1个方法。先准备参数的值
	var params []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(40))
	// 调用第1个方法,并传入参数
	res := val.Method(0).Call(params)
	// 返回结果是[]reflect.Value
	fmt.Println("res =", res[0].Int())
}

func main() {
    
    
	var aa = Monster{
    
    
		Name:  "黄鼠狼精",
		Age:   400,
		Score: 60.5,
	}
	TestStruct(aa)
}

运行命令:

go run .\main.go

运行结果如下

struct has 4 fields
Field 0 值: 黄鼠狼精
Field 0 tag: name
Field 1 值: 400
Field 1 tag: monster_name
Field 2 值: 60.5
Field 3 值:
struct has 3 methods
-----start--------
{黄鼠狼精 400 60.5 }
-----end--------
res = 50

3、对反射结构体进行测试

package main

import (
	"reflect"
	"testing"
)

type User struct {
    
    
	UserId string
	Name   string
}

func TestReflectStructPtr(t *testing.T) {
    
    
	var (
		model *User
		st    reflect.Type
		elem  reflect.Value
	)
	st = reflect.TypeOf(model) // 获取*User
	t.Log("reflect.TypeOf =", st.Kind().String())
	st = st.Elem() // st指向User
	t.Log("reflect.TypeOf.Elem = ", st.Kind().String())
	elem = reflect.New(st)

	t.Log("reflect.New = ", elem.Kind().String())
	t.Log("reflect.New.Elem =", elem.Elem().Kind().String())
	model = elem.Interface().(*User)
	elem = elem.Elem()
	elem.FieldByName("UserId").SetString("654321")
	elem.FieldByName("Name").SetString("jack")
	t.Log("model model.Name", model, model.Name)
}

运行命令:

go test -v

运行结果:

=== RUN   TestReflectStructPtr
    user_test.go:20: reflect.TypeOf = ptr
    user_test.go:22: reflect.TypeOf.Elem =  struct
    user_test.go:25: reflect.New =  ptr
    user_test.go:26: reflect.New.Elem = struct
    user_test.go:31: model model.Name &{654321 jack} jack
--- PASS: TestReflectStructPtr (0.00s)
PASS
ok      go_code/project02/demo03/zuoye01        0.022s

猜你喜欢

转载自blog.csdn.net/xiaojin21cen/article/details/124614184