首页 文章 Go语言基础 golang使用reflect与tag修改结构体参数
1
0
0
305

golang使用reflect与tag修改结构体参数

接口(interface)与反射(reflect) struct结构体 参数 reflect 结构 golang tag

eg. 现有结构体Foo如下

type Foo struct {
	TID string `json:"tid"`
	Content string `json:"content"`
	AID string `json:"aid"`
	Type string `json:"type"`

	Params map[string]interface{}
}

传入map字段,当map的key值与tag中json字段的值一致,且数据类型一致的时候,进行赋值,否则添加到变量Params中

func (foo *Foo) Parsing(data map[string]interface{}) {
    typeOfHMX := reflect.TypeOf(*foo)
    // 对指针需要使用Elem()
    valueOfHMX := reflect.ValueOf(foo).Elem()
​
    if foo.Params == nil {
        foo.Params = make(map[string]interface{})
    }
​
    for k, v := range data {
        wasFound := false
        for i := 0; i < typeOfHMX.NumField(); i ++ {
            filedType := typeOfHMX.Field(i)
            if filedType.Tag.Get("json") == k && filedType.Type == reflect.TypeOf(v) {
                valueOfHMX.FieldByName(filedType.Name).Set(reflect.ValueOf(v))
                wasFound = true
                break
            }
        }
        if !wasFound {
            foo.Params[k] = v
        }
    }
}

其中,reflect.Value类型还有个Convert类型,也就是说,valueOfHMX.FieldByName(filedType.Name).Set(reflect.ValueOf(v))可以改为类似valueOfHMX.FieldByName(filedType.Name).Set(reflect.ValueOf(v).Convert(filedType.Type))进行适配,但这种转化并不是普通的转化,举个例子,数字111转为字符串会被转为字母o。若想将不为同类型的进行赋值,且不影响值,比如说传入的data为{"tid":111},而Foo的TID为string类型,此时应该将data字段转化为string类型,之后再使用reflect.ValueOf获取转化后的值。但较为麻烦,因为涉及了两个不同类型的转换,如果需要转换为string倒是最简单的了。

举个简单例子,如下

func (foo *Foo) Parsing(data map[string]interface{}) {
    typeOfHMX := reflect.TypeOf(*foo)
    // 对指针需要使用Elem()
    valueOfHMX := reflect.ValueOf(foo).Elem()
​
    if foo.Params == nil {
        foo.Params = make(map[string]interface{})
    }
​
    for k, v := range data {
        wasFound := false
        for i := 0; i < typeOfHMX.NumField(); i ++ {
            filedType := typeOfHMX.Field(i)
            if filedType.Tag.Get("json") == k {
            // 为string类型时可使用fmt较快转换,其他类型较为复杂
                if valueOfHMX.FieldByName(filedType.Name).Kind() == reflect.String {
                    valueV := fmt.Sprint(v)
                    valueOfHMX.FieldByName(filedType.Name).Set(reflect.ValueOf(valueV))
                    wasFound = true
                }
                break
            }
        }
        if !wasFound {
            foo.Params[k] = v
        }
    }
}

 

到此这篇关于“golang使用reflect与tag修改结构体参数”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持Go语言编程!

相关文章

创建博客

开始创作
写作能提升自己能力,也能为他人分享知识。

在线教程

查看更多
  • Go入门指南

    Go入门指南

  • Go语言高级编程

    Go语言高级编程

  • Go Web 编程

    Go Web 编程

  • GO专家编程

    GO专家编程

  • Go语言四十二章经

    Go语言四十二章经

  • 数据结构和算法(Golang实现)

    数据结构和算法(Golang实现)

Go语言编程网

微信扫码关注订阅号


博客 资讯 教程 我的