23 05 2025
package main

import (
"fmt"
"reflect"
)

type myint int
type Person struct {
Name string `json:"name" validate:"required"` //多个标签用空格分隔
Age  int    `json:"age" validate:"gte=0,lte=120"`
}

func (p Person) SayHello() {
fmt.Println("Hello, my name is", p.Name, "and I am", p.Age, "years old.")
}

// 反射获取任意变量的类型
func reflectfn(x interface{}) {
v := reflect.TypeOf(x)
//v.Name() 获取类型名
//v.Kind() 获取类型种类 底层类型
fmt.Printf("类型: %v, 类型名称: %v, 类型种类: %v\n", v, v.Name(), v.Kind())
}
func reflectvalue(x interface{}) {
//反射获取变量的原始值
v := reflect.ValueOf(x)
//v.kind() 获取变量种类
kind := v.Kind()
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
fmt.Printf("Int原始值: %v, 类型: %T\n", v.Int(), v.Int())
case reflect.Float32, reflect.Float64:
fmt.Printf("Float原始值: %v, 类型: %T\n", v.Float(), v.Float())
case reflect.String:
fmt.Printf("String原始值: %v, 类型: %T\n", v.String(), v.String())
case reflect.Bool:
fmt.Printf("Bool原始值: %v, 类型: %T\n", v.Bool(), v.Bool())
case reflect.Slice:
fmt.Printf("Slice原始值: %v, 类型: %T\n", v, v)
case reflect.Array:
fmt.Printf("Array原始值: %v, 类型: %T\n", v, v)
case reflect.Map:
fmt.Printf("Map原始值: %v, 类型: %T\n", v, v)
case reflect.Struct:
fmt.Printf("Struct原始值: %v, 类型: %T\n", v, v)
case reflect.Ptr:
fmt.Printf("Ptr原始值: %v, 类型: %T\n", v, v)
default:
fmt.Printf("默认原始值: %v, 类型: %T\n", v, v)
}
}
func reflectsetvalue(x interface{}, y interface{}) {
//反射设置变量的值
v := reflect.ValueOf(x)
// v.Set(reflect.ValueOf(y))
v.Elem().Set(reflect.ValueOf(y))
fmt.Printf("设置后变量的值: %v, 类型: %T\n", v.Elem(), v.Elem())
}
func (p *Person) Setval(name string, age int) {
p.Name = name
p.Age = age
}

// 结构体操作
func structfn(x interface{}) {
t := reflect.TypeOf(x)
if t.Kind() == reflect.Ptr {
t = t.Elem() // 获取指针指向的实际类型
}
if t.Kind() != reflect.Struct {
fmt.Println("不是结构体类型")
return
}
//t.Field(下标) 获取结构体的属性
field0 := t.Field(0)
fmt.Printf("值: %#v\n", field0)
fmt.Println("字段名:", field0.Name)
fmt.Println("字段tag:", field0.Tag.Get("json"))
fmt.Println("字段tag:", field0.Tag.Get("validate"))
fmt.Println("-----------")
// FieldByName 获取结构体的属性
field1, ok := t.FieldByName("Age")
if ok {
fmt.Printf("值: %#v\n", field1)
fmt.Println("字段名:", field1.Name)
fmt.Println("类型:", field1.Type)
fmt.Println("字段tag:", field1.Tag.Get("json"))
fmt.Println("字段tag:", field1.Tag.Get("validate"))
}
//获取结构体属性的数量
fmt.Println("结构体属性数量:", t.NumField())
//通过ValueOf FieldByName 获取值
v := reflect.ValueOf(x)
fmt.Println(v.Elem().FieldByName("Name"))
//循环获取
for i := 0; i < t.NumField(); i++ {
field3 := t.Field(i)
field4 := v.Elem().Field(i)
fmt.Printf("值: %#v, 字段名: %s, 类型: %s, tag: %s\n", field4, field3.Name, field3.Type, field3.Tag)
}
//获取方法
method1 := t.Method(0) //跟方法顺序没关系 跟方法名称ASCII码有关系
fmt.Println(method1.Name)
fmt.Println(method1.Type)
fmt.Println("-------------------")
method2, ok := t.MethodByName("SayHello")
if ok {
fmt.Println(method2.Name)
fmt.Println(method2.Type)
}
//调用方法
v.Method(0).Call([]reflect.Value{})
v.MethodByName("SayHello").Call([]reflect.Value{})
var params []reflect.Value
params = append(params, reflect.ValueOf("Bob"))
params = append(params, reflect.ValueOf(30))
v.Method(1).Call(params)
v.MethodByName("Setval").Call(params)
v.Method(0).Call(nil)
v.MethodByName("SayHello").Call(nil)
fmt.Println(t.NumMethod(), v.NumMethod())
//修改值
v.Elem().Field(0).SetString("Tom")
v.Elem().Field(1).SetInt(35)
fmt.Println(v.Elem().Field(0).String())
fmt.Println(v.Elem().Field(1).Int())
v.MethodByName("SayHello").Call(nil)
}
func main() {
a := 10
b := 20.5
c := "hello"
d := true
e := []int{1, 2, 3, 4, 5}
f := map[string]int{"one": 1, "two": 2, "three": 3}
g := Person{"Alice", 25}
h := myint(30)
i := [3]int{1, 2, 3}
reflectfn(a)
reflectfn(b)
reflectfn(c)
reflectfn(d)
reflectfn(e)
reflectfn(f)
reflectfn(g)
reflectfn(h)
reflectfn(i)
reflectfn(&a) //传入指针变量
reflectvalue(a)
reflectvalue(b)
reflectvalue(c)
reflectvalue(d)
reflectvalue(e)
reflectvalue(f)
reflectvalue(g)
reflectvalue(h)
reflectvalue(i)
reflectvalue(&a)          //传入指针变量
reflectsetvalue(&a, 30)   //设置指针变量的值
reflectsetvalue(&b, 30.5) //设置指针变量的值
structfn(&g)
}

延伸阅读
学习golang(六)
学习golang(四)
golang连接数据库 增删改查以及事物
学习golang(七)
学习golang(八)
发表评论
最新|与我有关