golang反射学习笔记

reflect包

  • 任何接口由两部分组成
    • 类型
      • 在反射中可以理解为reflect.Type
      • 在反射中可以理解为reflect.Value

reflect.TypeOf()

  • 作用:获取变量的类型对象
  • 使用:v := reflect.TypeOf(a)
  • 返回值:变量的类型对象,是reflect.Type类型
    • 返回值有两个属性:
      • v.Name() 获取类型,跟%T一样
      • v.Kind() 获取底层类型,底层类型有:
        • reflect.Invalid // 非法类型
        • reflect.Bool // 布尔型
        • reflect.Int // 有符号整型
        • reflect.Int8 // 有符号8位整型
        • reflect.Int16 // 有符号16位整型
        • reflect.Int32 // 有符号32位整型
        • reflect.Int64 // 有符号64位整型
        • reflect.Uint // 无符号整型
        • reflect.Uint8 // 无符号8位整型
        • reflect.Uint16 // 无符号16位整型
        • reflect.Uint32 // 无符号32位整型
        • reflect.Uint64 // 无符号64位整型
        • reflect.Uintptr // 指针
        • reflect.Float32 // 单精度浮点数
        • reflect.Float64 // 双精度浮点数
        • reflect.Complex64 // 64位复数类型
        • reflect.Complex128 // 128位复数类型
        • reflect.Array // 数组
        • reflect.Chan // 通道
        • reflect.Func // 函数
        • reflect.Interface // 接口
        • reflect.Map // 映射
        • reflect.Ptr // 指针
        • reflect.Slice // 切片
        • reflect.String // 字符串
        • reflect.Struct // 结构体
        • reflect.UnsafePointer // 底层指针
  • 举例:
package main

import (
	"fmt"
	"reflect"
)

func main() {
	type myInt int
	var num myInt = 10
	t := reflect.TypeOf(num)
	name := t.Name()
	kind := t.Kind()

	fmt.Println(name, kind) // main.myInt, int
}

reflect.ValueOf()

  • 作用:获取变量的值对象
  • 返回值: v := reflect.ValueOf(a)
    • 返回值有一个属性:
      • v.Kind() 获取底层类型,底层类型同上面reflect.TypeOf().Kind()的类型
    • 注意,reflect.ValueOf()下没有Name()

通过反射获取原始值

  • 返回值v.Int() 转成int类型的值(所有有符号的整型均可以此方法返回)
  • 返回值v.Uint() 转成unit类型的值(所有无符号的整型均可以此方法返回)
  • 返回值v.Float() 转成float64类型的值(所有float32、float64均可以此方法返回)
  • 返回值v.Bool() 转成bool
  • 返回值v.Bytes() 转成[]bytes类型
  • 返回值v.String() 转成字符串类型
  • 举例:
  var str float32 = 3.14
  strt := reflect.ValueOf(str)
  fmt.Println(strt.Float())

  var a int8 = 15
  at := reflect.ValueOf(a)
  fmt.Println(at.Int())

  var b bool = true
  bt := reflect.ValueOf(b)
  fmt.Println(bt.Bool())

  var c = []byte{'a', 'b', 'c'}
  ct := reflect.ValueOf(c)
  fmt.Println(ct.Bytes()) // [97 98 99]

  var d = "abcd"
  dt := reflect.ValueOf(d)
  fmt.Println(dt.String()) // abcd

通过反射设置变量的值

  • 要去改变值,就需要给reflect.ValueOf()的参数中,传入变量的指针,即:reflect.ValueOf(&a)
  • 语法:
    1. 【错误】返回值v.SetInt(200)这样修改的是副本,reflect包会引发panic
    2. 【正确】返回值v.Elem().SetInt(200) 用Elem()方法获取指针对应的值,然后修改
  • 判断指针的类型,也用Elem(),比如v.Elem().Kind() == reflect.Int64
  • 举例:将int64类型的值100,设置成200
  func reflectSetValue(x interface{}) {
    v := reflect.ValueOf(x)
    if v.Elem().Kind() == reflect.Int64 { // 注意v.Kind() 是reflect.Ptr,而v.Elem().Kind()是reflect.Int64
      v.Elem().SetInt(200) // 这里整数是SetInt,表示对底层的值进行修改,如果是其他类型就是Set其他的,比如字符串SetString()
    }
  }

  var number int64 = 100
  reflectSetValue(&number)
  fmt.Println(number) // 200

isNil() 和 isValid()

  • 语法:
    • v.isNil() 判断是否为nil
    • v.isValid() 是否为有效的值,判断是否为Value的零值,如果是则返回false,不是则返回true
  • 举例:
var a *int // 定义a为int类型空指针
  v := reflect.ValueOf(a)
  fmt.Println(v.IsNil())   // true
  fmt.Println(v.IsValid()) // true
  fmt.Println(v.IsZero())  // true

  n := map[int]string{1: "yh"}
  v = reflect.ValueOf(n)
  fmt.Println(v.IsNil())   // false
  fmt.Println(v.IsValid()) // true
  fmt.Println(v.IsZero())  // false

结构体反射

  • 判断是否为结构体
    • reflect.TypeOf(x).Kind() == reflect.Struct
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值