介绍go反射

// 反射
package main

import "fmt"
import (
	"reflect"
)

type User struct {
	Id   int
	Name string
	Age  int
}

type Manager struct {
	User
	Title string
}

func Info(obj interface{}) {

	t := reflect.TypeOf(obj)
	fmt.Println("type:", t.Name())

	if k := t.Kind(); k != reflect.Struct {
		fmt.Println("该对象不能反射")
		return
	}

	v := reflect.ValueOf(obj)
	for i := 0; i < v.NumField(); i++ {
		f := t.Field(i)
		val := v.Field(i).Interface()
		fmt.Printf("%6s:%v = %v\n", f.Name, f.Type, val)
	}

	for i := 0; i < t.NumMethod(); i++ {
		m := t.Method(i)
		fmt.Printf("%s : %v\n", m.Name, m.Type)
	}
}

func Set(obj interface{}) {
	v := reflect.ValueOf(obj)

	if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {
		fmt.Println("不允许修改值")
		return
	} else {
		v = v.Elem()
	}

	f := v.FieldByName("Name")
	if !f.IsValid() {
		fmt.Println("未找到字段Name")
		return
	}

	if f.Kind() == reflect.String {
		f.SetString("王五")
	}
}
func (u User) Hello(name string) {
	fmt.Println("你好:" + name)
}
func main() {
	user := User{Id: 1000, Name: "zhangsan", Age: 23}
	Info(user)

	manager := Manager{User: User{Id: 1001, Name: "lisi", Age: 24}, Title: "abc"}
	t := reflect.TypeOf(manager)
	//获取匿名字段
	fmt.Println(t.FieldByIndex([]int{0, 0})) // {Id  int  0 [0] false} false表示不是匿名字段
	fmt.Println(t.FieldByIndex([]int{0, 1})) // {Name  string  8 [1] false}

	// 修复变量的值
	x := 123
	v := reflect.ValueOf(&x)
	v.Elem().SetInt(456)
	fmt.Println(x) // 456

	Set(&user)
	fmt.Println(user) // {1000 王五 23}

	//调用方法
	va := reflect.ValueOf(user)
	mv := va.MethodByName("Hello")
	args := []reflect.Value{reflect.ValueOf("赵六")}
	mv.Call(args) // 你好:赵六
}

输出:

type: User

    Id:int = 1000

  Name:string = zhangsan

   Age:int = 23

Hello : func(main.User, string)

{Id  int  0 [0] false}

{Name  string  8 [1] false}

456

{1000 王五 23}

你好:赵六


你可能感兴趣的文章

评论区

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。