您的位置:首页 > 汽车 > 时评 > golang中通过反射获取结构体Tag标签定义的内容 函数和测试用例

golang中通过反射获取结构体Tag标签定义的内容 函数和测试用例

2025/1/6 0:41:26 来源:https://blog.csdn.net/tekin_cn/article/details/139371631  浏览:    关键词:golang中通过反射获取结构体Tag标签定义的内容 函数和测试用例

当我们在go语言中定义结构体的时候, 经常需要给某些字段打上一个Tag标签,  如 Name string `json:"name"·` , 那这个标签有和作用呢?  这个作用可大了,最为常用的是json序列化和反序列化, 还有各种ORM 的实体对象定义,这个Tag可是必不可少的。 今天给大家介绍的这个函数就是用来获取这个Tag中定义的值的函数, 废话不多说,直接上代码:

获取结构体Struct标签Tag的值函数GetStructTagVal

import ("fmt""reflect"
)// 获取一个结构体TAG中的指定tagKey的值, 如果没有对应的tagKey则返回空字符串和相应的错误信息
// structObj 结构体对象
// fieldName 结构体中定义的字段名称 区分大小写
// tagkey 结构体字段的Tag中定义的key,
//
//	    如: 结构体字段定义 Name string `json:"name" orm:"varchar(50) comment('名称')"`
//		这里的tagKey就是 json 或者 orm
//		获取到的值就是tagKey后面的双引号内的值,如tagkey为 orm 获取的值就是 varchar(50) comment('名称')
//
// @author tekintian <tekintian@gmail.com>
func GetStructTagVal(structObj interface{}, fieldName, tagKey string) (string, error) {refType := reflect.TypeOf(structObj)if refType.Kind() != reflect.Struct { //传入的数据非结构体类型,直接返回return "", fmt.Errorf("传入参数 %v 的类型为 %T , 非结构体类型!", structObj, structObj)}if fieldObj, ok := refType.FieldByName(fieldName); ok {// 这里的sfield.Tag.Get(tagKey) 直接返回的是一个字符串if tagVal, isOk := fieldObj.Tag.Lookup(tagKey); isOk {return tagVal, nil} else {return "", fmt.Errorf("在结构体 %v 字段 %v 中未找到tagkey为 %v 的定义", refType.Name(), fieldName, tagKey)}}return "", fmt.Errorf("在结构体 %v 中未找到 %v 字段的定义", refType.Name(), fieldName)
}// 根据结构体StructField获取tag标签的值 没有对应的tagkey将返回空字符串
//   - field: 通过反射获取的字段对应的结构体字段对象 reflect.TypeOf(structObj).FieldByName(fieldName)
//   - tagKey: tag标签的key
func GetStructTagValByStructField(fieldObj reflect.StructField, tagKey string) string {return fieldObj.Tag.Get(tagKey)
}

GetStructTagVal函数测试用例:

import ("testing"
)// GetStructTagVal单元测试用例
// @author tekintian <tekintian@gmail.com>
func TestGetStructTagVal(t *testing.T) {// 定义测试用例数据cases := []struct { // 测试用例输入参数和期望输出参数定义structObj anyfieldName stringtagkey    stringexpected  string // 预期结果}{{structObj: Person{}, fieldName: "Name", tagkey: "myorm", expected: "varchar(25) notnull unique 'usr_name' comment('姓名')"},{structObj: Person{}, fieldName: "age", tagkey: "json", expected: "age"},// 异常测试用例数据定义{structObj: Person{}, fieldName: "sex", tagkey: "json", expected: "在结构体 Person 中未找到 sex 字段的定义"},{structObj: Person{}, fieldName: "age", tagkey: "json1", expected: "在结构体 Person 字段 age 中未找到tagkey为 json1 的定义"},{structObj: 123, fieldName: "x", tagkey: "y", expected: "传入参数 123 的类型为 int , 非结构体类型!"}, // 这个直接就返回异常了}for _, v := range cases {t.Run(v.fieldName, func(t *testing.T) {tagVal, err := GetStructTagVal(v.structObj, v.fieldName, v.tagkey)// 这里如果异常信息不为空,且异常信息 等于期望的异常 或者 输出结果等于期望结果 测试成功if (err != nil && err.Error() == v.expected) || tagVal == v.expected {t.Log(tagVal) // 测试通过,打印日志信息} else {// 测试失败的情况// 有异常且是非期望的异常if err != nil {t.Fatal(err) // 测试失败,打印异常信息} else {// 结果不等于预期 测试失败t.Fatalf("test failed, expected '%v', got '%v'", v.expected, tagVal)}}})}
}

参考 reflect package - reflect - Go Packages

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com