goalng struct剖析(嵌套结构体/匿名结构体/tag)
goalng struct
目录
结构体(struct)
结构体是用户自定义的类型,它代表若干字段的集合,可以用于描述一个实体对象,类似Java中的Class,是golang面向对象编程的基础类型.
因为 Go 语言中没有类的概念,所以在 Go 中结构体有着更为重要的地位
语法:type <Name> struct{}
添加对象方法:
func(t *T) funcName(){
}
初始化的方法:
#按原始字段顺序创建结构体 p := T{1, 2} #照自定义字段顺序进行初始化 p := T{Y:1, X:2} #通过new函数创建 p1 := new(T) T.X = 1 T.Y = 2
结构体嵌套
go中使用结构体嵌套来扩展类型
嵌入到结构体中的字段,完全可以当作自己是自己的字段
type ST struct{ X, Y float64 }
type FT struct {
ST
Value int
}
结构体FT嵌套了结构体ST,此时FT就拥有了ST的字段X,Y.可以通过“.”来操作,如果ST拥有自己的方法,那么FT也可以使用这些方法,而不需要自己再定义.
用这种方式,内嵌可以使我们定义字段特别多的复杂类型,我们可以将字段先按小类型分组,然后定义小类型的方法,之后再把它们组合起来
编译器查找方法的顺序:
- 先在本结构体定义的方法中找
- 找不到,再去子结构体找,然后一直递归向下找
如果选择器有二义性的话编译器会报错,比如你有一个字段叫Test,然后一个方法也叫Test,那么选择器就不知道你想使用的是哪个,编译器就会报错
匿名结构体
匿名结构体就是在嵌入时,不指定名称,这样子会将匿名结果体的所有方法引入到该类型中;这样在使用时有很多便利:例如下面对map的操作;
我们知道map时非线程安全的,会存在读或写竞争,我们需要在对map的操作时进行加锁
package main
// 匿名结构提嵌套,可以引入匿名结构体所有的方法
import (
"fmt"
"sync"
)
type safeMap struct {
sync.Mutex
mapping map[string]string
}
// 获取map中元素的值
func (m safeMap) Get(key string) (value string) {
// 引入了sync.Mutex的加锁和解锁方法
m.Lock()
value = m.mapping[key]
m.Unlock()
return
}
func main() {
m := map[string]string{
"a" : "alpha",
"i" : "integer",
}
cache := safeMap{
mapping: m,
}
fmt.Println(cache.Get("a"))
fmt.Println(cache.Get("i"))
}
因为sync.Mutex字段也被嵌入到了这个struct里,其Lock和Unlock方法也就都被引入到了这个匿名结构中了,这让我们能够以一个简单明了的语法来对其进行加锁解锁操作
Tag
Go的struct声明允许字段附带Tag来对字段做一些标记.
该Tag不仅仅是一个字符串那么简单,因为其主要用于反射场景, reflect包中提供了操作Tag的方法,所以Tag写法也要遵循一定的规则.
Tag的本质
Tag的规则
Tag本身是一个字符串,当字符串却是 以空格分隔的key:value对
- key:必须是非空字符串,字符串不能包含控制字符.空格.引号.冒号.
- value:以双引号标记的字符串.
- 注意:冒号前后不能有空格
Tag字符说明:
type Server struct{
ServerName string `key1:"value1" key2:"value2"`
ServerIp string `key2:"value3`
}
// A StructField describes a single field in a struct.
type StructField struct {
// Name is the field name.
Name string
...
Type Type // field type
Tag StructTag // field tag string
...
}
type StructTag string
获取Tag
StructTag 提供了 Get(key string)string 方法来获取Tag
Tag存在的意义
使用反射可以动态的给结构体成员赋值,正是因为有tag,在赋值前可以使用tag来决定赋值的动作.
比如,官方的 encoding/json 包,可以将一个JSON数据 Unmarshal 进一个结构体,此过程中就是用了Tag,该包定义一些规则,
只要参考改规则设置tag就可以将不同的JSON数据转换成结构体.
总之:正是基于struct的tag特性,才有了诸如json. orm等等的应用.理解这个关系是至关重要的.或许,你可以定义另一种tag规则,来处理你特有的数据.
Tag常见用法
常见的Tag用法,主要是JSON数据解析,ORM映射等.
参考内容:
https://www.cnblogs.com/vinsent/p/11536637.html
《GO 专家编程》
上一篇: go语言-内存回收机制GC
下一篇: Unity中Spine动画的骨骼控制