reflect反射

reflect反射

方法归纳

t:=reflect.TypeOf(o) //获取类型
v:=reflect.ValueOf(o) //获取值
t.NumField() //获取结构体字段个数
t.Field(i) //取每个字段
v.Field(i).Interface() //获取字段对应的值

v = v.Elem() // 获取指针指向的元素
fild := v.FieldByName("Name")  // 取字段
v.FieldByName("Age").SetInt(20)  //改年龄

m := v.MethodByName("Hello") // 获取方法
name:=v.Field(1).Interface() // 反射获取结构体字段对应的值
args := []reflect.Value{reflect.ValueOf(name)}  //构建参数
// 没参数的情况下:var args2 []reflect.Value
m.Call(args) // 调用方法,需要传入方法的参数


t := reflect.TypeOf(o) //获取类型
k:=t.NumMethod()  //绑定方法数量
m := t.Method(0) //获取方法
fmt.Println(m.Name) //获取绑定方法名称
fmt.Println(m.Type) //获取结构体类型

reflect.DeepEqual //判断两个map是否相等

结构体反射

遍历结构体绑定的所有方法

package main

import (
	"fmt"
	"reflect"
)

func Poni(o interface{}) {

	t := reflect.TypeOf(o) //获取类型
	k:=t.NumMethod()  //绑定方法数量
	fmt.Println(k) //2

	for i:=0;i<k;i++{
		m := t.Method(i) //获取方法
		fmt.Println(m.Name) //获取绑定方法名称
		fmt.Println(m.Type) //获取结构体类型
	}
}

type Users struct {
	Id   int
	Name string
	Age  int
}

// 绑方法1
func (u Users) Hello() {
	fmt.Println("Hello word")
}

// 绑方法2
func (u Users) Hello2() {
	fmt.Println("Hello word2")
}

func main() {
	u := Users{1, "jeff", 18}
	Poni(u)
}

查看结构体类型、字段和方法

t := reflect.TypeOf(o) //获取类型
v := reflect.ValueOf(o) //获取值
count := t.NumField() //获取结构体字段个数
f := t.Field(i) //取每个字段
val := v.Field(i).Interface() //获取字段对应的值
package main

import (
	"fmt"
	"reflect"
)

// 定义结构体
type Users struct {
	Id   int
	Name string
	Age  int
}

// 绑方法
func (u Users) Hello() {
	fmt.Println("Hello word")
}

// 传入interface{}
func Poni(o interface{}) {
	//获取类型
	t := reflect.TypeOf(o)
	fmt.Println("类型:", t) //类型: main.Users
	fmt.Println("字符串类型:", t.Name())  //字符串类型: Users
	
	// 获取值
	v := reflect.ValueOf(o)
	fmt.Println(v)  //{1 jeff 18}
	
	// 可以获取所有属性
	// 获取结构体字段个数:t.NumField()
	for i := 0; i < t.NumField(); i++ {
		// 取每个字段
		f := t.Field(i)
		fmt.Println(f.Name, f.Type) //Id int
		
		// 获取字段的值信息
		// Interface():获取字段对应的值
		val := v.Field(i).Interface()
		fmt.Println("data:", val)  // data: 1
	}
	fmt.Println("=================方法====================")
	for i := 0; i < t.NumMethod(); i++ {
		m := t.Method(i)
		fmt.Println(m.Name) // Hello
		fmt.Println(m.Type) //func(main.Users)
	}
	
}

func main() {
	u := Users{1, "jeff", 18}
	Poni(u)
}

查看匿名字段

package main

import (
	"fmt"
	"reflect"
)

// 定义结构体
type Users struct {
	Id   int
	Name string
	Age  int
}

// 匿名字段
type Boy struct {
	Users
	Addr string
}

func main() {
	m := Boy{Users{1, "jeff", 18}, "shanghai"}
	t := reflect.TypeOf(m)
	fmt.Println(t) //main.Boy
	// Anonymous:匿名
	fmt.Printf("%#v\n", t.Field(0))
	// 值信息
	fmt.Printf("%#v\n", reflect.ValueOf(m).Field(0)) //main.Users{Id:1, Name:"jeff", Age:18}
}

//

main.Boy
reflect.StructField{Name:"Users", PkgPath:"", Type:(*reflect.rtype)(0x10bb140), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
main.Users{Id:1, Name:"jeff", Age:18}

修改结构体的值

v := reflect.ValueOf(o)  
v = v.Elem() // 获取指针指向的元素
f := v.FieldByName("Name")  // 取字段
v.FieldByName("Age").SetInt(20)  //改年龄
package main

import (
	"fmt"
	"reflect"
)

// 定义结构体
type Users struct {
	Id   int
	Name string
	Age  int
}

// 修改结构体值
func SetValue(o interface{}) {
	v := reflect.ValueOf(o)
	// 获取指针指向的元素
	v = v.Elem()
	// 取字段
	f := v.FieldByName("Name")
	if f.Kind() == reflect.String {
		f.SetString("chary")
	}
	//改年龄
	v.FieldByName("Age").SetInt(999)
}

func main() {
	u := Users{1, "jeff", 18}
  fmt.Println(u)  //{1 jeff 18}
	SetValue(&u)
	fmt.Println(u) //{1 chary 999}
}

//
{1 chary 20}

调用方法

m := v.MethodByName("Hello") // 获取方法
name:=v.Field(1).Interface() // 反射获取结构体字段对应的值
args := []reflect.Value{reflect.ValueOf(name)}  //构建参数
// 没参数的情况下:var args2 []reflect.Value
m.Call(args) // 调用方法,需要传入方法的参数
package main

import (
	"fmt"
	"reflect"
)

// 定义结构体
type Users struct {
	Id   int
	Name string
	Age  int
}

func (u Users) Hello(name string) {
	fmt.Println("Hello:", name)
}

func main() {
	u := Users{1, "jeff", 18}
	v := reflect.ValueOf(u)
	// 获取方法
	m := v.MethodByName("Hello")
	
	// 反射获取结构体字段对应的值
	name:=v.Field(1).Interface()
	// 构建一些参数
	args := []reflect.Value{reflect.ValueOf(name)}
	// 没参数的情况下:var args2 []reflect.Value
	// 调用方法,需要传入方法的参数
	m.Call(args)
}

//
Hello:jeff

获取字段的tag

package main

import (
	"fmt"
	"reflect"
)

type Student struct {
	Name string `json:"name1" db:"name2"`
}

func main() {
	var s Student
	v := reflect.ValueOf(&s)
	// 类型
	t := v.Type()
	// 获取字段
	f := t.Elem().Field(0)
	fmt.Println(f.Tag.Get("json")) //name1
	fmt.Println(f.Tag.Get("db"))  //name2
}

reflect.DeepEqual 判断两个map是否相等

reflect.DeepEqual(m1, m2) // 判断两个map是否相等
package main

import (
	"fmt"
	"reflect"
)

func main() {
  // m1,m2顺序不一样,做比较
	m1 := map[string]interface{}{"a": 1, "b": 2, "c": 3}
	m2 := map[string]interface{}{"a": 1, "c": 3, "b": 2}

	fmt.Println(reflect.DeepEqual(m1, m2))  // true
}

通过字符串段修改结结构对应字段的值

user := &User{}
fieldName:="userName"
fieldName = strings.Title(fieldName)
fieldValue := reflect.ValueOf(user).Elem().FieldByName(fieldName)
	if fieldValue.IsValid() && fieldValue.CanSet() {
		fieldValue.SetUint(2)
	}
posted @ 2023-10-06 22:05  Jeff的技术栈  阅读(20)  评论(0编辑  收藏  举报
回顶部