Go反射学习条记

[复制链接]
发表于 2025-11-5 00:59:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1、从范例对象中获取名称和种类

  1. const (
  2.         Zero int = 0
  3. )
  4. func main() {
  5.         type stu struct{}
  6.         typeofCat := reflect.TypeOf(stu{})
  7.         fmt.Println(typeofCat.Name(), typeofCat.Kind()) //显示反射类型对象名称和种类
  8.         typeOfA := reflect.TypeOf(Zero)
  9.         fmt.Println(typeOfA.Name(), typeOfA.Kind())
  10. }
复制代码
2、利用反射获取布局体的成员范例

方法分析Field(i int) StructField根据索引规返回索引对应的布局字段的信息,当值不是布局体或索引越界会发生宕机NumField() int返回布局体成员字段数量,当范例不是布局体或索引越界时发生宕机FieldByName(name string) (StructField bool)根据给定字段返回字符串对应的布局体字段的信息,没有找到时bool返回false,当范例不是布局体或索引越界时发生宕机FieldByIndex(index[]int) StructField多层成员访问时,根据[]iny 提供的每个布局体的字段索引,返回字段的信息,没有找到返回零值。当范例不是布局体或索引越界时发生宕机FieldByNameFunc(match func(string) bool)(StructField,bool)根据匹配函数匹配必要的字段,当值不是布局体或索引越界时发生宕机3、从反射值对象中获取值的方法

方法名分析Interface() interface{}将值以interface{}范例返回,可以通过范例断言为指定范例Int() int64将值以int范例返回,全部有符号整数均可以此方式返回Uint() uint64将值以uint范例返回,全部无符号整数均可以此方式返回Float() float64将值以双精度范例返回,全部浮点数(float32,float64)均可以此方式返回Bool() bool将值以bool范例返回Bytes() []bytes将值以字节数组[]bytes范例返回String() string将值以字符串范例返回
  1. func main() {
  2.         var m int = 2021
  3.         valueOfA := reflect.ValueOf(m)
  4.         var getA int = valueOfA.Interface().(int)
  5.         var getA2 int = int(valueOfA.Int())
  6.         fmt.Println(getA, getA2)
  7. }
复制代码
4、利用反射访问布局体的成员字段的值

方法分析Field(i int) Value根据索引对应的布局体成员字段的反射对象,当值不是布局体或索引越界时发生宕机NumField() int返回给布局体成员字段数量 ,当值不是布局体或索引越界时发生宕机FieldByName(name string) Value根据给定字符串返回字符串对应的布局体字段,没有找到时返回零值,当值不是布局体或索引越界时发生宕机FieldByIndex(index []int) Value多层成员返回时,根据[]int提供的每个布局体的字段索引,返回字段的值,没有找到时返回零值,当值不是布局体或索引越界时发生宕机FieldByNameFunc(match func(string) bool) value根据匹配函数匹配必要的字段,找到时返回零值,当值不是布局体或索引越界时发生宕机
  1. type stu struct {
  2.         a int
  3.         b string
  4.         float32
  5.         bool
  6.         next *stu
  7. }
  8. func main() {
  9.         d := reflect.ValueOf(stu{
  10.                 next: &stu{},
  11.         })
  12.         fmt.Println("numField", d.NumField())
  13.         floatField := d.Field(2)
  14.         fmt.Println("floatField", floatField.Type())
  15.         //根据名称查找字段
  16.         fmt.Println("FieldsByName().Type", d.FieldByName("b").Type())
  17.         fmt.Println("FieldByIndex()", d.FieldByIndex([]int{4, 0}).Type())
  18. }
复制代码
5、反射对象的空和有效性判断

| 方法 | 分析 |
| IsNil() bool | 返回值是否为nil,假如值范例不是通道(channel)、函数、接口、map、指针切片,类似于语言层的v==nil操纵|
| IsValid() bool | 判断值是否有效。当值本身非法时,返回false,如reflect Value不包罗任何值,值为nil等|
  1. func main() {
  2.         var a *int
  3.         fmt.Println("var a *int:", reflect.ValueOf(a).IsNil())
  4.         fmt.Println("nil:", reflect.ValueOf(nil).IsValid())
  5.         fmt.Println("*int nil:", reflect.ValueOf((*int)(nil)).Elem().IsValid())
  6.         s := struct{}{}
  7.         fmt.Println("struct:", reflect.ValueOf(s).FieldByName("").IsValid())
  8.         fmt.Println("并不存在的结构体方法:", reflect.ValueOf(s).MethodByName("").IsValid())
  9.         m := map[int]int{}
  10.         fmt.Println("不存在的键:", reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
  11. }
复制代码
6、判断及获取元素的干系方法

方法名分析Elem() Value取值指向的元素值,类似于语言层* 操纵,当值范例不是指针或接口时发生宕机,空指针时返回nil的ValueAddr() Value对寻址的值返回其地点,类似于语言层&操纵,当值不可寻址时发生宕机CanAddr() bool表现值是否可寻址CanSet() bool返回值可否被修改,要求值可寻址且是导出的字段7、值修改的干系方法

Set(x Value)将值设置为传入反转值对象的值SetUint(x uint64)利用uint64设置值,当值的范例不是uint,uint8,uint16,uint32,uint64会发生宕机SetInt(x int64)比上面少了uSetFloat(x float64)利用float54设置值,当值的范例不是float32,float64发生宕机SetBool(x bool)利用bool设置值,当值的范例不是bool时发生宕机SetBytes(x []byte)设置字节数组[] bytes值,当值的范例不是[]byte 会发生宕机SetString(x string)设置字符串值.当值的范例不是string时会发生宕机

  • 可被寻址
  • 可被导出
  1. func main() {
  2.         a := 1024
  3.         valueOfA := reflect.ValueOf(&a)
  4.         valeOfEl := valueOfA.Elem()
  5.         valeOfEl.SetInt(100)
  6.         fmt.Println(a)
  7. }
复制代码
  1. func main() {
  2.         type Dog struct {
  3.                 LegCount int
  4.         }
  5.         valueOfDog := reflect.ValueOf(&Dog{})
  6.         valueOfDog = valueOfDog.Elem()
  7.         vLegCount := valueOfDog.FieldByName("LegCount")
  8.         vLegCount.SetInt(3)
  9.         fmt.Println(vLegCount.Int())
  10. }
复制代码
8、通过范例创建范例

创建了新的范例
  1. func main() {
  2.         var a int
  3.         typeOfA := reflect.TypeOf(a)
  4.         aIns := reflect.New(typeOfA)
  5.         fmt.Println(aIns.Type(), aIns.Kind())
  6. }
复制代码
9、利用反射调用函数

  1. func add(a, b int) int {
  2.         return a + b
  3. }
  4. func main() {
  5.         funcValue := reflect.ValueOf(add)
  6.         paramList := []reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)}
  7.         retList := funcValue.Call(paramList)
  8.         fmt.Println(retList[0].Int())
  9. }
复制代码
10、常用反射API

从实例到Value

  1. func ValueOf(i interface{}) Value
复制代码
从实例到Type

  1. func TypeOf (i interface{}) Type
复制代码
从Type到Value

  1. func NewAt (type Type,p unsafe.Pointer) Value
复制代码
从Value到Type

  1. func (v Value) Type() Type
复制代码
从Value到实例

  1. func (v Value) Interface() (i interface{})
  2. func (v Value)  Bool() bool
  3. func (v Value) Float() float64
  4. func (v Value) Int() int64
  5. func (v Value) Uint() uint64
复制代码
从Value的指针到值

  1. func (v Value) Elem() Value
  2. func Indirect(v Value) Value
复制代码
Type指针和值相互转换

  1. t.Elem() Type //指针类型Type到值类型Type
  2. func PtrTo(t Type) Type
复制代码
Value值的可修改性

  1. func (v Value) CanSet() bool
  2. func (v Value) Set(x Value)
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表