Golang – 反射编程
反射编程会增加程序的复杂读和性能开销较大所以在使用的时候需要谨慎。通常使用反射编程都是灵活编程的需要。
package main
import (
"errors"
"fmt"
"log"
"reflect"
)
type Employee struct {
EmployeeId int
Name string
Age int
}
type Customer struct {
CustomerId int
Name string
Age int
}
// fillBySetting 函数接收一个结构体对象的指针和一个键值对的 map,
// 将 map 中的值填充到结构体对象的相应字段中
func fillBySetting(object interface{}, settings map[string]interface{}) error {
// 判断 object 是否是指针类型
if reflect.TypeOf(object).Kind() != reflect.Ptr {
// 如果不是指针类型,判断 object 当中的元素是否是 struct 类型
if reflect.TypeOf(object).Elem().Kind() != reflect.Struct {
return errors.New("object 必须是 struct 类型")
}
}
// 如果传入的 settings 是空的,就返回错误
if settings == nil {
return errors.New("settings 是空的")
}
// 遍历 settings map
for k, v := range settings {
// 检查 struct 中是否有对应的字段名
field, ok := reflect.TypeOf(object).Elem().FieldByName(k)
if !ok {
continue // 如果没有对应字段,跳过
}
// 检查字段类型是否与传入值类型匹配
if field.Type == reflect.TypeOf(v) {
// 获取 struct 的值
vstr := reflect.ValueOf(object)
vstr = vstr.Elem() // 获取指针指向的元素
// 设置 struct 中对应字段的值
vstr.FieldByName(k).Set(reflect.ValueOf(v))
}
}
return nil // 成功完成后返回 nil
}
func main() {
// 创建一个 settings map
settings := map[string]interface{}{"Name": "kiat", "Age": 11}
e := Employee{}
// 调用 fillBySetting 函数,填充 Employee 结构体
err := fillBySetting(&e, settings)
if err != nil {
log.Fatalln(err)
}
// 打印填充后的 Employee 结构体
fmt.Println(e)
c := new(Customer)
// 调用 fillBySetting 函数,填充 Customer 结构体
err1 := fillBySetting(c, settings)
if err1 != nil {
log.Fatalln(err1)
}
// 打印填充后的 Customer 结构体
fmt.Println(c)
}
输出结果:
{0 kiat 11}
&{0 kiat 11}
以下是使用Reflect找出 variable type
package main
import (
"fmt"
"reflect"
)
// checkType 函数检查传入的接口类型并打印其类型信息
func checkType(v interface{}) {
// 获取传入变量的反射类型
t := reflect.TypeOf(v)
// 根据类型的种类进行判断
switch t.Kind() {
// 如果是浮点数类型
case reflect.Float32, reflect.Float64:
fmt.Println("float")
// 如果是整数类型
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
fmt.Println("int")
// 如果是其他类型
default:
fmt.Println("unknown", t)
}
}
func main() {
// 示例调用
checkType(10) // 输出: int
checkType(3.14) // 输出: float
checkType("string") // 输出: unknown string
}
Facebook评论