golang反射的基本使用、通过反射获取结构体标签案例

更新时间:2023-07-25 11:49:34 阅读: 评论:0

golang反射的基本使⽤、通过反射获取结构体标签案例
golang 反射的基本使⽤、通过反射获取结构体标签案例
⼀、反射简介
⾸先⼤概介绍⼀下反射,在Go中的反射是由 reflect 包提供⽀持的,它定义了两个重要的类型 Type 和 Value,
任何接⼝值都可以使⽤reflect包中的reflect.TypeOf 和 reflect.ValueOf两个函数去获取其对应的reflect.Type和reflect.Value
单人独马⼆、reflect.Type
对于任意接⼝值,我们可以通过调⽤reflect.TypeOf函数获取reflect.Type类型的对象,从⽽获取动态类型信息。
值得注意的是如果传⼊的变量是⼀个机构体,那么reflect.Type对象可以调⽤Field等⽅法来获取reflect.StructField结构体。
这个结构体内包含了结构体变量字段的⼀些例如字段的类型、字段的标签、等信息,其中PkgPath字段是⾮导出字段的包路径,对导出字段该字段为空,由此可以判断结构体字段的导出性数字代表
简单⽰例如下:
package main
import(
"fmt"
三倍角公式"reflect"
"testing"
)
func TestType(t *testing.T){
a :=struct{
Say string
weight int
}{
Say:"Cello golang",
weight :111,
}
typeOfA := reflect.TypeOf(a)
fmt.Printf("a 的类型是%s \n", typeOfA.Kind())
for i :=0; i < typeOfA.NumField(); i++{
structField := typeOfA.Field(i)
if structField.PkgPath ==""{
fmt.Printf("字段%s可导出",structField.Name)
}el{
fmt.Printf("字段%s不可导出",structField.Name)
}实习报告内容
fmt.Printf("类型是%s\n",structField.Type)
}
}
reflect.Value
reflect.ValueOf⽅法可以得到变量的值信息,利⽤reflect.ValueOf返回的是⼀个reflect.Value结构体类型,
reflect.Value提供给我们⼀些⽅法可以获取变量保存的值,同时也提供了诸如SetFloat、SetString等⽅法去设置变量的值
要注意的是想要设置变量的值的时候,传⼊reflect.ValueOf的必须是个指针,因为值类型的传递是拷贝
了⼀个副本,并不能改变原始变量的值
并且要通过reflect.Elem()⽅法获取这个指针指向的元素类型,这个获取过程被称为取元素,等效于对指针类型变量做了⼀个*操作。
代码如下:
package main
import(
"reflect"写事的作文400字
"testing"
)
func TestValue(t *testing.T){
var a string="Hello golang"
v := reflect.ValueOf(&a)
t.Logf("v 映射的类型是 %v\n", v.Type())
v.Elem().SetString("Hi")
t.Logf("现在a 的值是 %v", a)
}
通过反射实现结构体字段校验
下⾯分享⼀个通过结构体标签,进⾏结构体字段的长度判断、前后去空格的⽅法:package main
import(
"fmt"
"reflect"
"strconv"
"strings"
"testing"
)
//测试⽤例
func TestLength(t *testing.T){
//tag-length ⽤于最⼤长度判断
//tag-must ⽤于空值判断
var testDatas =[]struct{
Name string`length:"10" must:"Y"`
Age  string`length:"2" must:"Y" `
want string
}{
{
Name:" 123456789 ",
Age:" 22222 ",
want:"Age字段长度不能⼤于2个字符",
},
{
Name:"",
Age:"10",
want:"Name字段不能为空",
},
{
Name:"⼩张",
Age:"18",
want:"",
},
}
消防主题for_,tt :=range testDatas{
verifyResult :=VerifyStructField(&tt)
if  verifyResult != tt.want {
t.Errorf("verifyResult is %s but want %s",verifyResult,tt.want)
}
}
}
//验证结构体字段
func VerifyStructField(inStruct interface{})(verifyResult string){
rType := reflect.TypeOf(inStruct)
rVal := reflect.ValueOf(inStruct)
if rType.Kind()== reflect.Ptr {
rType = rType.Elem()
rVal = rVal.Elem()
}el{
return fmt.Sprintf("必须传⼊指针")
}
for i :=0; i < rType.NumField(); i++{
tFiled := rType.Field(i)
五险一金和社保有什么区别vFiled := rVal.Field(i)
must := tFiled.Tag.Get("must")
tagLength := tFiled.Tag.Get("length")
if tFiled.Type.Kind()== reflect.String {
v := vFiled.String()
v = strings.Trim(v," ")
if must =="Y"&&len(v)==0{
return fmt.Sprintf("%s字段不能为空", tFiled.Name)
}
if tagLength !=""{
filedLen :=len(v)
length,_:= strconv.Atoi(tagLength)
if filedLen > length {
return fmt.Sprintf("%s字段长度不能⼤于%s个字符", tFiled.Name, tagLength) }
}
if tFiled.PkgPath ==""{
vFiled.Set(reflect.ValueOf(v))
}
发烧可以跑步吗}
}
return
}

本文发布于:2023-07-25 11:49:34,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1116354.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:结构   获取   变量
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图