package main
import (
"fmt"
"reflect"
)
func reflectType(obj any) {
typeObj := reflect.TypeOf(obj)
switch typeObj.Kind() {
case reflect.Struct:
fmt.Println("struct")
case reflect.Ptr:
fmt.Println("ptr")
case reflect.Func:
fmt.Println("func")
case reflect.Array:
fmt.Println("array")
case reflect.Slice:
fmt.Println("slice")
case reflect.Map:
fmt.Println("map")
case reflect.Chan:
fmt.Println("chan")
case reflect.String:
fmt.Println("string")
case reflect.Bool:
fmt.Println("bool")
case reflect.Int:
fmt.Println("int")
case reflect.Invalid:
fmt.Println("invalid")
default:
fmt.Println("unknown")
}
}
func getValue(obj any) reflect.Value {
typeObj := reflect.TypeOf(obj)
switch typeObj.Kind() {
case reflect.Int:
return reflect.ValueOf(int(obj.(int)))
case reflect.String:
return reflect.ValueOf(obj.(string))
default:
panic("unhandled default case")
}
return reflect.Value{}
}
func setValue(source any, val reflect.Value) {
v1 := reflect.ValueOf(source)
// 检查是否是指针
if v1.Kind() != reflect.Ptr {
return
}
// 解引用获取实际值
elem := v1.Elem()
// 检查类型是否匹配,且是否可设置
if elem.Kind() != val.Kind() || !elem.CanSet() {
return
}
switch elem.Kind() {
case reflect.String:
elem.SetString(val.String())
case reflect.Int:
elem.SetInt(val.Int())
}
}
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
IsMarried bool
}
func (p *Person) SetName(name string) {
p.Name = name
}
// 反射读取修改结构体
func ModifyStruct(obj any) {
v := reflect.ValueOf(obj).Elem() //获取指针对应的值 returns the value that the interface v contains
t := reflect.TypeOf(obj).Elem() //获取指针对应的类型 returns a type's element type.
for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
jsonTag := field.Tag.Get("json")
if jsonTag == "" {
jsonTag = field.Name
}
// 读取值
var val = v.Field(i)
fmt.Println(jsonTag, val, field.Type)
if field.Type.Kind() == reflect.String {
// 修改值
val.SetString(val.String() + "10")
} else if field.Type.Kind() == reflect.Int {
val.SetInt(val.Int() + 10)
} else if field.Type.Kind() == reflect.Bool {
val.SetBool(!val.Bool())
}
}
fmt.Println("修改字段后:", obj)
// 这儿读取的解引用后方法, Person没有方法
for i := 0; i < v.NumMethod(); i++ {
m := t.Method(i)
fmt.Println("Person方法名:", m.Name, m.Type)
}
// 带指针的方法
for i := 0; i < reflect.ValueOf(obj).NumMethod(); i++ {
m := reflect.TypeOf(obj).Method(i)
fmt.Println("*Person方法名:", m.Name, m.Type)
method := reflect.ValueOf(obj).Method(i)
method.Call([]reflect.Value{reflect.ValueOf("新的名字")})
}
fmt.Println("调用方法后:", obj)
}
func main() {
reflectType(3)
reflectType("hello")
reflectType(struct {
Name string
Age int
}{"Jack", 18})
tmp := getValue("hello")
fmt.Println(tmp)
var name = "TT"
var age = 33
setValue(&name, reflect.ValueOf("ee"))
fmt.Println(name)
setValue(&age, reflect.ValueOf(18))
fmt.Println(age)
var p = Person{"Tom", 118, true}
ModifyStruct(&p)
}