内容包括
-
用interface{}接收值
-
判断interface{}的类型 switch
-
打印interface{}的类型
-
通过字符串对结构体,interface{}等进行设置值、获取值处理
示例代码
Go
package main
import (
"fmt"
"log"
"reflect"
)
type Student2 struct {
Id1 int `json:"jsonTag1" db:"name2"`
Name1 string
age1 int
}
func reflectValue(a interface{}) {
log.Println("================ reflect value start ==================")
// 类型判断
switch a.(type) {
case float64:
log.Println("a type is :", "float64")
case float32:
log.Println("a type is :", "float32")
default:
log.Println("a type is :", "default")
}
// 打印类型
aType := reflect.TypeOf(a)
log.Println("a type is:", aType)
// 获取值
aValue := reflect.ValueOf(a)
log.Println("a value is :", aValue.Float())
// 设置值报错,不传指针就没办法设置值
// 报错信息:panic: reflect: reflect.Value.SetFloat using unaddressable value
// aValue.SetFloat(32.11)
// log.Println("a value is :", aValue.Float())
log.Println("================ reflect value end ==================")
}
func reflectPoint(a interface{}) {
log.Println("================ reflect point start ==================")
// 打印类型
aType := reflect.TypeOf(a)
log.Println("a type is:", aType)
// 判断类型
aKind := aType.Kind()
switch aKind {
case reflect.Float64:
log.Println("a kind is :", "float64")
case reflect.Float32:
log.Println("a kind is :", "float32")
case reflect.Pointer:
log.Println("a kind is :", "Pointer")
}
// 获取参数
aValue := reflect.ValueOf(a)
log.Println("a value is :", aValue.Elem().Float())
// 设置参数
aValue.Elem().SetFloat(32.1)
log.Println("a value is :", aValue.Elem().Float())
log.Println("================ reflect point end ==================")
}
func reflectStructValue(a interface{}) {
log.Println("================ reflect struct value start ==================")
// 获取类型
aType := reflect.TypeOf(a)
log.Println("a type of :", aType)
log.Println("a type name :", aType.Name())
// 获取值{100 name1 13}
aValue := reflect.ValueOf(a)
log.Println("a value of :", aValue)
// 根据名称获取字段
// 如果外边传的是value则没法赋值,如果传的是$stu地址 则可以复制
name1Filed := aValue.FieldByName("Name1")
if name1Filed.Kind() == reflect.String && name1Filed.CanSet() {
name1Filed.SetString("name1111111111")
}
// 遍历属性
fieldNum := aType.NumField()
for i := 0; i < fieldNum; i++ {
field := aType.Field(i)
value := aValue.Field(i)
// 这里得看属性是否大小写,如果小写没法子获取他的值
// panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
// 获取字段标记:field.Tag.Get("json")
if value.CanInterface() {
log.Println("属性:", field.Name, field.Type, value.Interface(), field.Tag.Get("json"))
} else {
log.Println("属性:", field.Name, field.Type)
}
}
// 遍历方法
// func (stu Student2) Say() 可以获取到
// func (stu *Student2) Say() aType.NumMethod就没法获取到了
methodNum := aType.NumMethod()
for i := 0; i < methodNum; i++ {
method := aType.Method(i)
log.Println("方法:", method.Name, method.Type)
}
// 根据名称获取方法,并执行
sayMethod := aValue.MethodByName("Say")
args := []reflect.Value{reflect.ValueOf("message1111")}
sayMethod.Call(args)
log.Println("================ reflect struct value end ==================")
}
func reflectStructPoint(a interface{}) {
log.Println("================ reflect struct point start ==================")
// 获取值{100 name1 13}
aValue := reflect.ValueOf(a)
log.Println("a value of :", aValue.Elem().Interface())
// 根据名称获取字段
// 如果外边传的是value则没法赋值,如果传的是$stu地址 则可以复制
name1Filed := aValue.Elem().FieldByName("Name1")
if name1Filed.Kind() == reflect.String && name1Filed.CanSet() {
name1Filed.SetString("name1111111111")
}
log.Println("a value of :", a)
log.Println("a value of :", aValue.Elem().Interface())
log.Println("================ reflect struct point start ==================")
}
func (stu Student2) Say(message string) {
log.Println("student say:", stu, message)
}
func main() {
log.Println("main ...")
var f float64 = 10
// 传地址可以修改
reflectPoint(&f)
// 传值就不能修改
reflectValue(f)
stu := Student2{100, "name1", 13}
stu.Say("1111")
reflectStructValue(stu)
reflectStructPoint(&stu)
fmt.Println("success ...")
}
参考: