Go语言之 Struct Tag

简介:

在上一篇介绍Go反射的时候,提到了如何通过反射获取Struct的Tag,这一篇文章主要就是介绍这个的使用和原理,在介绍之前我们先看一下JSON字符串和Struct类型相互转换的例子。


JSON字符串对象转换


func main() {
    var u User
    h:=`{"name":"张三","age":15}`
    err:=json.Unmarshal([]byte(h),&u)    
    if err!=nil{
        fmt.Println(err)
    }else {
        fmt.Println(u)
    }
}
type User struct{    Name string `name`    Age int `age`
}


上面这个例子就是Json字符串转User对象的例子,这里主要利用的就是User这个结构体对应的字段Tag,json解析的原理就是通过反射获得每个字段的tag,然后把解析的json对应的值赋给他们。


利用字段Tag不光可以把Json字符串转为结构体对象,还可以把结构体对象转为Json字符串。


 newJson,err:=json.Marshal(&u)
 fmt.Println((string(newJson)))


接着刚刚的例子,这样就可以转为一个新的字符串了,通过打印输出,可以看到和开始输入的字符串一样。


反射获取字段Tag


字段的Tag是标记到字段上的,所以我们可以通过先获取字段,然后再获取字段上的Tag。


func main() {
    var u User

    t:=reflect.TypeOf(u)    
    for i:=0;i<t.NumField();i++{
        sf:=t.Field(i)
        fmt.Println(sf.Tag)
    }
}


获取字段上一篇我们提到过,获取字段后,调用.Tag就获取到对应的Tag字段了。


字段Tag的键值对


很多时候我们的一个Struct不止具有一个功能,比如我们需要JSON的互转、还需要BSON以及ORM解析的互转,所以一个字段可能对应多个不同的Tag,以便满足不同的功能场景。


Go Struct 为我们提供了键值对的Tag,来满足我们以上的需求。


func main() {
    var u User
    t:=reflect.TypeOf(u)    
    for i:=0;i<t.NumField();i++{
        sf:=t.Field(i)
        fmt.Println(sf.Tag.Get("json"))
    }
}
type User struct{    Name string `json:"name"`    Age int `json:"age"`
}


以上的例子,使用了键值对的方式配置Struct Tag,Key-Value以冒号分开,这里的Key为json,所以我们可以通过这个Key获取对应的值,也就是通过.Tag.Get("json"))方法。Get方法就是通过一个Key获取对应的tag设置。


除此之外,我们还可以设置多个Key,来满足我们上面说的场景。


func main() {
    var u User
    t:=reflect.TypeOf(u)    
    for i:=0;i<t.NumField();i++{
        sf:=t.Field(i)
        fmt.Println(sf.Tag.Get("json"),",",sf.Tag.Get("bson"))
    }
}
type User struct{    Name string `json:"name" bson:"b_name"`    Age int `json:"age" bson:"b_age"`
}


多个Key使用空格进行分开,然后使用Get方法获取不同Key的值。


Struct Tag可以提供字符串到Struct的映射能力,以便我们作转换,除此之外,还可以作为字段的元数据的配置,提供我们需要的配置,比如生成Swagger文档等。



本文转自 baby神 51CTO博客,原文链接:http://blog.51cto.com/babyshen/2044189,如需转载请自行联系原作者
相关文章
|
5天前
|
存储 前端开发 Go
Go语言中的数组
在 Go 语言中,数组是一种固定长度的、相同类型元素的序列。数组声明时长度已确定,不可改变,支持多种初始化方式,如使用 `var` 关键字、短变量声明、省略号 `...` 推断长度等。数组内存布局连续,可通过索引高效访问。遍历数组常用 `for` 循环和 `range` 关键字。
|
6天前
|
Go 调度 开发者
Go语言中的并发编程:深入理解与实践###
探索Go语言在并发编程中的独特优势,揭秘其高效实现的底层机制。本文通过实例和分析,引导读者从基础到进阶,掌握Goroutines、Channels等核心概念,提升并发处理能力。 ###
|
2天前
|
存储 安全 算法
Go语言是如何支持多线程的
【10月更文挑战第21】Go语言是如何支持多线程的
98 72
|
2天前
|
安全 大数据 Go
介绍一下Go语言的并发模型
【10月更文挑战第21】介绍一下Go语言的并发模型
21 14
|
1天前
|
安全 Go 开发者
go语言并发模型
【10月更文挑战第16天】
16 8
|
2天前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
15 7
|
1天前
|
安全 Java Go
go语言高效切换
【10月更文挑战第16天】
10 5
|
1天前
|
运维 监控 Go
go语言轻量化
【10月更文挑战第16天】
8 3
|
1天前
|
安全 Go 调度
Go语言中的并发编程:解锁高性能程序设计之门####
探索Go语言如何以简洁高效的并发模型,重新定义现代软件开发的边界。本文将深入剖析Goroutines与Channels的工作原理,揭秘它们为何成为实现高并发、高性能应用的关键。跟随我们的旅程,从基础概念到实战技巧,一步步揭开Go并发编程的神秘面纱,让您的代码在多核时代翩翩起舞。 ####
|
2天前
|
Go 调度 开发者
Go语言多线程的优势
【10月更文挑战第15天】
8 4