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)
- 语法:
- 【错误】返回值v.SetInt(200)这样修改的是副本,reflect包会引发panic
- 【正确】返回值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
《本文》有 2536 条评论