1.内嵌字段
Go语言的结构体没有继承的概念,当需要“复用”其他结构体时,需要使用组合方式将其他结构体嵌入当前结构体。
type Animal struct{
Name string
}
type Cat struct{
Animal//隐式指定,产生了一个隐式同名Animal字段
}
type Dog struct{
a Animal//显式指定
}
c := Cat{}
c.Animal.Name = "B"
c.Name = "b"
当你的外部结构中存在和内部的同名变量时,优先访问外部的该变量
2. 方法受体
- 一般的函数声明如下:
func 函数名(参数){函数体}
- 方法的声明:
func (接受者) 函数名 (参数){函数体}
//在当前package中Name和age字段在可见性上没有区别
type People struct{
Name string//对包内和包外均可见
age int//仅对包内可见
}
//起作用,方法的受体为People的拷贝对象,修改不会反映到原对象中
func (p *People) SetName(name string){
p.Name = name
}
//不起作用,方法的受体为People的指针对象,修改会反映到原对象中
func (p People) SetName2(name string){
p.Name = name
}
3. 字段标签
Go语言的struct声明中允许为字段标记Tag
type typeMeta struct{
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}
每个字段后面两个反单引号中间的字符串就是字段的Tag
3.1 Tag的本质
3.1.1 Tag是Struct的一部分
用于表示字段的额外属性,有点类似于注释。
在reflect包中,使用结构体StructField表示结构体的一个字段
type StructField struct{
Name string //字段名
Type Type //字段类型
Tag StructTag //Tag
...
}
// StructTag是string的一个别名
type StructTag string
3.1.2 Tag的约定
约定的格式,字符串由key:"value"组成
`json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
- key:必须是非空字符串,字符串不嗯呢该包含控制字符、空格、引号、冒号
- value:以双引号标记的字符串
- key和value之间使用冒号分隔,冒号前后不能有空格。多个key:"value"之间使用空格分开
- key一般表示用途
- json表示控制结构体和json格式数据的转换规则
- protobuf表示控制序列化和反序列化
- value表示控制指令
3.1.3 获取Tag
func PrintTag(){
t := TypeMeta{}
ty := reflect.TypeOf(t)
for i:=0;i<ty.NumField();i++{
fmt.Printf(ty.Field(i).Name)
//获取某个字段的Tag
fmt.Printf(ty.Field(i).Tag)
//获取其中的某个key的值
fmt.Printf(ty.Field(i).Tag.Get("json"))
}
}
3.2 Tag的意义
在Go语言中,结构体(struct)的标签(tag)是一种特殊类型的元数据,它可以附加到结构体字段上,用来为字段提供额外的信息或指令,这些信息主要用于反射(reflection)机制中,使得程序能够在运行时动态地了解和操作结构体字段的特性。结构体标签的语法是使用反引号(`)包围的字符串,通常格式为 key:“value”,其中key-value对可以有多个,通过空格分隔。
结构体标签的主要意义和用途包括:
- 序列化与反序列化:最典型的用途是在进行JSON、XML等数据格式的编码和解码时,通过特定的标签(如json:“name,omitempty”)来控制字段的名称、是否忽略空值等行为。
- 验证工具:一些验证库(如validate)会读取结构体字段的标签来确定验证规则,比如字段是否必填、长度限制等。
- ORM映射:在数据库对象关系映射中,标签常用于指定数据库表的列名、数据类型、唯一性约束等信息。
- API文档生成:某些工具可以从结构体标签中提取信息,用于自动生成API文档,如字段的描述信息。
- 定制化编码与解码逻辑:除了基本的序列化库之外,自定义的编码或解码逻辑也可以依赖结构体标签来实现特定的处理逻辑。
- 提供额外的上下文信息:为开发人员或库的使用者提供有关字段用途或限制的提示,虽然这部分信息在编译时并不起直接作用,但增加了代码的可读性和维护性。
结构体标签是Go语言中一种强大的特性,它增强了代码的灵活性和可扩展性,特别是在处理数据序列化、验证、以及与其他系统交互的场景下尤为重要。