golang reflect反射方式修改对象的值 reflect.Value对象中的SetX类型(xxx) 和 Set(x reflect.Value) 方法的区别和使用总结

golang通过反射修改对象的值中的 reflect.Value 对象里面的方法 SetInt, SetUint, SetString, SetBool, SetFloat 方法和 Set(x reflect.Value) 方法的使用完整示例如下, 这个东西必须在代码里面才能看明白,使用说明和区别已经在代码里做了详细注释,详细如下:

reflect.Value对象中的SetX类型(xxx) 和 Set(x reflect.Value) 方法示例

import (
	"fmt"
	"reflect"
)

func main() {
	type Person struct {
		Name string `json:"name"`
		Age int `json:"age"`
		Money float64 `json:"money"`
	}

	p := Person{}
	rt := reflect.TypeOf(p)
	for i := 0; i < rt.NumField(); i++ {
		field := rt.Field(i)
		if field.CanSet() {
			switch field.Kind() {
			case reflect.String:

				// 注意这种设置方式是使用反射对象提供的指定大类型方法设置 
				field.SetString("Hello world!") 

				 // 这种设置方式设置的是ValueOf类型,这个方式设置的值必须和case的值完全匹配,否则panic
				field.Set(reflect.ValueOf("Hello world!"))

			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				// 注意这里case了多个类型, 这个情况就不能使用field.Set方法,否则设置的值和实际值不匹配就panic
				// 但是这里可以使用反射提供的 field.SetInt() 来兼容case里面的多种数据 
				// 注意reflect.Value里面提供的大类型设置方法有 SetInt SetUint SetBool SetString SetFloat 等方法,这些大类型就可以兼容其中的小类型

				// 这里可以使用 field.SetInt方法来兼容int int8 .... int64等int序列类型
				field.SetInt(123) 

				// ps: 在这个case里面是不能使用field.Set(reflect.ValueOf(xxx)) 的!!! 虽然语法没有问题,但是当设置的数据类型和要设置的字段的类型不完全匹配时就panic了!!!
			}

		}
	}

}


golang反射对象函数 对象和方法定义参考

了解下面的这些函数, 对象和方法的定义对应我们学习golang的放射至关重要!!

func Copy(dst, src Value) int // 数据拷贝函数
func DeepEqual(x, y any) bool // 深度相等比较函数
func Swapper(slice any) func(i, j int) // 交换函数

type ChanDir
    func (d ChanDir) String() string

type Kind // 反射类别
    func (k Kind) String() string

type MapIter // map类型数据迭代对象定义
    func (iter *MapIter) Key() Value
    func (iter *MapIter) Next() bool
    func (iter *MapIter) Reset(v Value)
    func (iter *MapIter) Value() Value

type Method // 方法定义,这个用于通过放射处理对象中的方法 如动态调用对象方法等
    func (m Method) IsExported() bool

type SelectCase
type SelectDir
type SliceHeader  DEPRECATED
type StringHeader  DEPRECATED

type StructField // 结构体字段类型定义, 用于处理结构体字段
    func VisibleFields(t Type) []StructField
    func (f StructField) IsExported() bool

type StructTag // 结构体标签定义
    // 结构体标签对象中的方法定义  这里的方法就是我们常见的结构体的tag处理的相关方法,如大名鼎鼎的结构体json标签就是用的下面这个方法
    func (tag StructTag) Get(key string) string
    func (tag StructTag) Lookup(key string) (value string, ok bool)

type Type // 放射类型定义
    // 用于获取Type的函数定义
    func ArrayOf(length int, elem Type) Type
    func ChanOf(dir ChanDir, t Type) Type
    func FuncOf(in, out []Type, variadic bool) Type
    func MapOf(key, elem Type) Type
    func PointerTo(t Type) Type
    func PtrTo(t Type) Type  DEPRECATED
    func SliceOf(t Type) Type
    func StructOf(fields []StructField) Type
    func TypeFor[T any]() Type
    func TypeOf(i any) Type

type Value // 放射中的Value对象定义
    // 下面这些都是用于获取Value对象的函数定义
    func Append(s Value, x ...Value) Value
    func AppendSlice(s, t Value) Value
    func Indirect(v Value) Value
    func MakeChan(typ Type, buffer int) Value
    func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value
    func MakeMap(typ Type) Value
    func MakeMapWithSize(typ Type, n int) Value
    func MakeSlice(typ Type, len, cap int) Value
    func New(typ Type) Value
    func NewAt(typ Type, p unsafe.Pointer) Value
    func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)
    func SliceAt(typ Type, p unsafe.Pointer, n int) Value
    func ValueOf(i any) Value
    func Zero(typ Type) Value

    // 下面这些都是Value对象的方法定义
    func (v Value) Addr() Value
    func (v Value) Bool() bool
    func (v Value) Bytes() []byte
    func (v Value) Call(in []Value) []Value
    func (v Value) CallSlice(in []Value) []Value
    func (v Value) CanAddr() bool
    func (v Value) CanComplex() bool
    func (v Value) CanConvert(t Type) bool
    func (v Value) CanFloat() bool
    func (v Value) CanInt() bool
    func (v Value) CanInterface() bool
    func (v Value) CanSet() bool
    func (v Value) CanUint() bool
    func (v Value) Cap() int
    func (v Value) Clear()
    func (v Value) Close()
    func (v Value) Comparable() bool
    func (v Value) Complex() complex128
    func (v Value) Convert(t Type) Value
    func (v Value) Elem() Value
    func (v Value) Equal(u Value) bool
    func (v Value) Field(i int) Value
    func (v Value) FieldByIndex(index []int) Value
    func (v Value) FieldByIndexErr(index []int) (Value, error)
    func (v Value) FieldByName(name string) Value
    func (v Value) FieldByNameFunc(match func(string) bool) Value
    func (v Value) Float() float64
    func (v Value) Grow(n int)
    func (v Value) Index(i int) Value
    func (v Value) Int() int64
    func (v Value) Interface() (i any)
    func (v Value) InterfaceData() [2]uintptr  DEPRECATED
    func (v Value) IsNil() bool
    func (v Value) IsValid() bool
    func (v Value) IsZero() bool
    func (v Value) Kind() Kind
    func (v Value) Len() int
    func (v Value) MapIndex(key Value) Value
    func (v Value) MapKeys() []Value
    func (v Value) MapRange() *MapIter
    func (v Value) Method(i int) Value
    func (v Value) MethodByName(name string) Value
    func (v Value) NumField() int
    func (v Value) NumMethod() int
    func (v Value) OverflowComplex(x complex128) bool
    func (v Value) OverflowFloat(x float64) bool
    func (v Value) OverflowInt(x int64) bool
    func (v Value) OverflowUint(x uint64) bool
    func (v Value) Pointer() uintptr
    func (v Value) Recv() (x Value, ok bool)
    func (v Value) Send(x Value)
    func (v Value) Seq() iter.Seq[Value]
    func (v Value) Seq2() iter.Seq2[Value, Value]
    func (v Value) Set(x Value)
    func (v Value) SetBool(x bool)
    func (v Value) SetBytes(x []byte)
    func (v Value) SetCap(n int)
    func (v Value) SetComplex(x complex128)
    func (v Value) SetFloat(x float64)
    func (v Value) SetInt(x int64)
    func (v Value) SetIterKey(iter *MapIter)
    func (v Value) SetIterValue(iter *MapIter)
    func (v Value) SetLen(n int)
    func (v Value) SetMapIndex(key, elem Value)
    func (v Value) SetPointer(x unsafe.Pointer)
    func (v Value) SetString(x string)
    func (v Value) SetUint(x uint64)
    func (v Value) SetZero()
    func (v Value) Slice(i, j int) Value
    func (v Value) Slice3(i, j, k int) Value
    func (v Value) String() string
    func (v Value) TryRecv() (x Value, ok bool)
    func (v Value) TrySend(x Value) bool
    func (v Value) Type() Type
    func (v Value) Uint() uint64
    func (v Value) UnsafeAddr() uintptr
    func (v Value) UnsafePointer() unsafe.Pointer
    
type ValueError
    func (e *ValueError) Error() string

总结:我们通过使用reflect.Value对象里面提供的SetX类型(xxx)方法可以兼容小类型,如SetInt方法可以兼容 int, int8 ,int16... int64, 而如果我们使用Set(x reflect.Value)方法,那么我们必须对每个小类型都必须设置一个case 否则在设置类型和数据类型不完全匹配时就panic。 建议使用SetX类型(xxx)方法,这样可以让你的代码看上去更精简。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值