视频加载失败

【Golang】使用反射实现验证struct必填字段是否为空

466 字
2 分钟
【Golang】使用反射实现验证struct必填字段是否为空
【Golang】使用反射实现验证struct必填字段是否为空

0x0#

反射:#

golang的reflect包实现了运行时的反射能力。reflect包中有两个重要函数:

  • reflect.TypeOf 获取数据类型信息,其类型为reflect.Type
  • reflect.ValueOf 获取数据运行时的信息,其类型为reflect.Value

Tag#

golang的struct中的每一个字段(field)后添加一段注释,称为 field tag,最经典就是构建json的struct,例如:

type Login struct{
UserName string `json:"user_name"`
Password string `json:"password"`
}

其中 json:"user_name" json:"password"就是 field tag

0x1#

假设现有一 struct:

type Note struct {
Time time.Time
Content string
Remarks string
}

我们想要指定一些字段非空,例如:Content != ""

按照一般通用的方法就是一个一个用if判断:

if content != "" { ... } else { ... }

如果只有几个字段需要这样判断还可以这样写。但如果有许多个字段或不同字段有不同类型,这样写的话就是一堆 if else,就不是很优雅。

0x2#

现在可以使用反射来更为优雅实现这一功能。只需要在struct需要非空的字段后添加一个 tag来标记,这个tag可以自定义,如:

type Note struct {
Time time.Time `must:"true"`
Content string `must:"true"`
Remarks string
}

其中 must:"true"为我们自定义的tag,表示该字段非空。

0x3#

我们可以通过反射来获取struct字段的tag:

fmt.Println(reflect.TypeOf(&note).Elem().Field(0).Tag.Get("must")) //获取第一个字段tag中"must"的值

0x4#

完整实现代码:

type Note struct {
Time time.Time `must:"true"`
Content string `must:"true"`
Remarks string
}
func validator(value interface{}) {
val := reflect.ValueOf(value).Elem() //获取字段值
typ := reflect.TypeOf(value).Elem() //获取字段类型
// 遍历struct中的字段
for i := 0; i < typ.NumField(); i++ {
// 当struct中的tag为 must:"true" 且当前字段值为空值时,输出
if typ.Field(i).Tag.Get("must") == "true" && val.Field(i).IsZero() {
fmt.Println("Fail:", typ.Field(i).Name, "is null")
return
}
}
fmt.Println("Pass")
}
func main() {
note1 := Note{
Time: time.Now(),
Content: "content",
Remarks: "",
}
validator(&note1)
// Pass
note2 := Note{
Time: time.Now(),
Content: "",
Remarks: "",
}
validator(&note2)
// Fail: Content is null
}

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
【Golang】使用反射实现验证struct必填字段是否为空
https://rehtt.com/posts/249/
作者
Rehtt
发布于
2021-08-20
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Rehtt
Hello, I'm Rehtt.
公告
欢迎来到我的博客!
分类
标签
最新动态
站点统计
文章
150
分类
17
标签
73
总字数
67,772
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录