go语言反射
反射的类型对象(reflect.Type)
在Go程序中,使用reflect.TypeOf()函数可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息。
反射的类型(Type)与种类(Kind)
在使用反射时,需要首先理解类型(Type)和种类(Kind)的区别。编程中,使用最多的是类型,但在反射中,当需要区分一个大品种的类型时,就会用到种类(Kind)。例如,需要统一判断类型中的指针时,使用种类(Kind)信息就较为方便,区分哪一个名称时候就需要用到(Name)
如下go语言中的数据类型
const (
Invalid Kind = iota // 非法类型
Bool // 布尔型
Int // 有符号整型
Int8 // 有符号8位整型
Int16 // 有符号16位整型
Int32 // 有符号32位整型
Int64 // 有符号64位整型
Uint // 无符号整型
Uint8 // 无符号8位整型
Uint16 // 无符号16位整型
Uint32 // 无符号32位整型
Uint64 // 无符号64位整型
Uintptr // 指针
Float32 // 单精度浮点数
Float64 // 双精度浮点数
Complex64 // 64位复数类型
Complex128 // 128位复数类型
Array // 数组
Chan // 通道
Func // 函数
Interface // 接口
Map // 映射
Ptr // 指针
Slice // 切片
String // 字符串
Struct // 结构体
UnsafePointer // 底层指针
)
Go程序中的类型(Type)指的是系统原生数据类型,如int、string、bool、float32等类型,以及使用type关键字定义的类型,这些类型的名称就是其类型本身的名称。例如使用type x struct{}定义结构体时,x就是struct{}的类型。种类(Kind)指的是对象归属的品种
go语言中反射修改基本类型值,在go语言中可以通过指针修改值
基本类型
示例如下
package main
import (
"fmt"
"reflect"
)
func main() {
var i int = 8
reflectType(i)
var array = []int {1,2,3}
reflectType(array)
reflectType(map[string]int{})
reflectType("字符串")
var cat = Cat{
name:"小花",
age : 1,
}
reflectType(cat)
reflectType(true)
var person = Person{
name:"小明",
age : 18,
}
reflectType(person)
//指针没有 name()
reflectType(&person)
}
//反射类型
func reflectType(x interface{}) {
//拿到x类型信息
T := reflect.TypeOf(x)
fmt.Printf("类型type : %v \n ",T)
//引用类型 name() 没有值
fmt.Printf("name : %s , kind : %s \n",T.Name(),T.Kind())
//fmt.Printf("%T \n ",T) //用的就是反射 打印类型
// ----------- 反射获取值类型 以及 值类型转换 ----
var a int32 = 8
reflectValue(a)
var b int64 = 8
reflectValue(b)
var c int = 8
reflectValue(c)
var d bool = false
reflectValue(d)
// 反射修改值
var m int = 11;
//由于go中函数传参是指拷贝,所以修改时候一般传地址
reflectSetValue(&m)
fmt.Printf("修改之后的值: %d \n " , m)
}
//反射修改基本类型值
func reflectSetValue( x interface{}) {
//
v := reflect.ValueOf(x)
kind := v.Kind() // 拿到值对应的种类
//如果是指针类型
if kind == reflect.Ptr{
//拿到值 传进来的是指针 必须先拿到指针 再拿值
fmt.Printf(" 转为int %d \n", v.Elem().Int())
//反射修改值
// .Elem() 取到指针再去修改值
v.Elem().SetInt( 1233)
}
}
//获取接口值信息
func reflectValue(x interface{}) {
//拿到接口值信息
v := reflect.ValueOf(x)
kind := v.Kind() // 拿到值对应的种类
switch kind {
case reflect.Int64:
i := v.Int() //反射中获取原来类型的值信息
fmt.Printf("当前值类型是:%s , 值是 %d \n ",v,i)
//自定义根据对应类型转
fmt.Printf(" 转为int64 %s \n", int64(i))
break
case reflect.Int32:
i := v.Int() //反射中获取原来类型的值信息
fmt.Printf("当前值类型是:%s , 值是 %d \n ",v,i)
//根据对应类型转
fmt.Printf(" 转为 int32 %s \n", int32(i))
break
case reflect.Int8:
i := v.Int() //反射中获取原来类型的值信息
fmt.Printf("当前值类型是:%s , 值是 %d \n ",v,i)
//根据对应类型转
fmt.Printf(" 转为 Int8 %s \n ", int8(i))
break
case reflect.String:
i := v.Int() //反射中获取原来类型的值信息
fmt.Printf("当前值类型是:%s , 值是 %d \n ",v,i)
//根据对应类型转
fmt.Printf(" 转为String %s \n", string(i))
break
case reflect.Bool:
i := v.Bool() //反射中获取原来类型的值信息
fmt.Printf("当前值类型是:%s , 值是 %b \n ",v,i)
//根据对应类型转
fmt.Printf(" 转为String %s \n",bool( i))
break
default:
fmt.Printf(" 默认返回 %s \n", v.String())
}
}
type Cat struct {
name string
age int8
}
type Person struct {
name string
age int8
}