package main
import (
"fmt"
"reflect"
)
func reflectType(x interface{}) {
obj := reflect.TypeOf(x)
fmt.Println(obj, obj.Name(), obj.Kind())
fmt.Printf("obj type of %T\n", obj)
}
func reflectValue(x interface{}) {
v := reflect.ValueOf(x)
fmt.Printf("value is a %v, type is a %T\n", v, v)
// 如何得到一个传入时候类型的变量
k := v.Kind() // 拿到值对应的类型种类
switch k {
case reflect.Float32:
ret := float32(v.Float())
fmt.Printf("value is a %v, type is a %T\n", ret, ret)
case reflect.Int32:
ret := int32(v.Int())
fmt.Printf("value is a %v, type is a %T\n", ret, ret)
}
}
func reflectSetValue(x interface{}) {
v := reflect.ValueOf(x)
// Elem()用来根据指针取对应的值
k := v.Elem().Kind()
switch k {
case reflect.Int32:
v.Elem().SetInt(100)
case reflect.Float32:
v.Elem().SetFloat(5.678)
}
}
type Cat struct{}
type Dog struct{}
func main() {
/*
var a float32 = 3.1415926
reflectType(a)
var b int8 = 10
reflectType(b)
// 结构体类型
var c Cat
reflectType(c)
var d Dog
reflectType(d)
// slice
var e []string
reflectType(e)
var f []int
reflectType(f)
*/
// valueOf
/*
var aa int32 = 100
reflectValue(aa)
var bb float32 = 3.1415926
reflectValue(bb)
*/
// setValue
var cc int32 = 10
reflectSetValue(&cc)
fmt.Println(cc)
}
isNil()和isValid()
package main
// IsNil()常被用于判断指针是否为空;IsValid()常被用于判定返回值是否有效。
import (
"fmt"
"reflect"
)
type StructField struct {
// Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""
Name string
PkgPath string
Type reflect.Type
Tag reflect.StructTag
Offset uintptr
Index []int
Anonymous bool
}
func main() {
// *int类型空指针
var a *int
fmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil())
// nil值
fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid())
// 实例化一个匿名结构体
b := struct{}{}
// 尝试从结构体中查找"abc"字段
fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid())
// 尝试从结构体中查找"abc"方法
fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid())
// map
c := map[string]int{}
// 尝试从map中查找一个不存在的键
fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid())
}
package main
import (
"fmt"
"reflect"
)
// 结构体反射
type student struct {
Name string `json:"name" ini:"s_name"`
Score int `json:"score" ini:"s_score"`
}
// 给student添加两个方法 Study和Sleep(注意首字母大写)
func (s student) Study() string {
msg := "好好学习,天天向上。"
fmt.Println(msg)
return msg
}
func (s student) Sleep() string {
msg := "好好睡觉,快快长大。"
fmt.Println(msg)
return msg
}
// 根据反射获取结构体中方法的函数
func printMethod(x interface{}) {
t := reflect.TypeOf(x)
fmt.Println(t.NumMethod())
v := reflect.ValueOf(x)
// 因为下面需要拿到具体的方法去调用,所以使用的是值信息
for i := 0; i < v.NumMethod(); i++ {
methodType := v.Method(i).Type()
fmt.Printf("method name:%s\n", t.Method(i).Name)
fmt.Printf("method:%s\n", methodType)
// 通过反射调用方法传递的参数必须是 []reflect.Value 类型
var args = []reflect.Value{}
v.Method(i).Call(args) // 调用方法
}
// 通过方法名获取结构体的方法
// t.MethodByName("Sleep") // reflect.Method, bool
methodObj := v.MethodByName("Sleep") // reflect.Value
fmt.Println(methodObj.Type())
}
func main() {
stu1 := student{
Name: "枫林神",
Score: 90,
}
/*
// 通过反射区获取结构体中的所有字段信息
t := reflect.TypeOf(stu1)
fmt.Printf("name :%v kind :%v\n", t.Name(), t.Kind())
// 遍历结构体变量的所有字段
for i := 0; i < t.NumField(); i++ {
//根据结构体字段的索引取字段
filedobj := t.Field(i)
fmt.Printf("name:%v type:%v tag:%v\n", filedobj.Name, filedobj.Type, filedobj.Tag)
fmt.Println(filedobj.Tag.Get("json"), filedobj.Tag.Get("ini"))
}
// 根据名字取结构体中的字段
filedobj2, ok := t.FieldByName("Score")
if ok {
fmt.Printf("name:%v type:%v tag:%v\n", filedobj2.Name, filedobj2.Type, filedobj2.Tag)
}
*/
printMethod(stu1)
}