1.内嵌字段:
Go语言没有继承的概念.当需要复用其他结构体时.需要使用组合方式将其他结构体嵌
入当前结构体.
示例:
type People struct {
Name string
}
func (p *People) SetName(name string) {
p.Name = name
}
type Student struct {
People
}
type Teacher struct {
p People
}
结构体中的字段既可以显示指定也可以隐式指定.
注:显示指定和隐示指定没有区别.仅代表某种类型的字段.
1.1访问方式:
type People struct {
Name string
}
func (p *People) SetName(name string) {
p.Name = name
}
type Student struct {
People
}
type Teacher struct {
People
}
func main() {
s := Student{}
s.SetName("student")
fmt.Println(s.Name)
s.People.SetName("student2")
fmt.Println(s.Name)
s.People.Name = "student3"
fmt.Println(s.Name)
}
2.访问受体:
一般函数声明:
func 函数名(参数){函数体}
方法声明:
func(接收者) 函数名(参数) {参数体}
方法一般用于类型的扩展方法.
示例:
type Student struct {
People
}
func (s Student) SetName(name string) {
s.Name = name
}
func (s *Student) UpdateName(name string) {
s.Name = name
}
SetName()方法的接收者为Student.UpdateName()方法为Student.*
示例:
func main() {
s := Student{}
s.SetName("setName")
fmt.Println(s.Name)
s.UpdateName("updateName")
fmt.Println(s.Name)
}
可以通过结果得知SetName()方法没有成功赋值.他两的执行逻辑虽然是一样的.但
是接收参数不一样.一个作用于对象.一个作用于指针.如果作用于对象.那么修改的是
当前对象的副本.如果作用指针.那么修改的是该对象的字段.
3.字段标签:
Go语言中Struct允许字段标记Tag.
示例:
type TypeMeta struct {
Kind string `json:"kind" yaml:"kind" protobuf:"bytes,1,opt,name=kind"`
Version string `json:"version"`
}
其中每个字段后面两个反引号中间的字符串就是Tag.
3.1Tag的本质:
3.1.1Tag是Struct的一部分:
Tag是用于标识结构体字段的额外属性.有点类似于注解.标准库reflect包中提供了操
作Tag的方法.
源码:runtime/reflect/type.go:StructField
type StructField struct {
// Name is the field name.
Name string
// PkgPath is the package path that qualifies a lower case (unexported)
// field name. It is empty for upper case (exported) field names.
// See https://golang.org/ref/spec#Uniqueness_of_identifiers
PkgPath string
Type Type // field type
Tag StructTag // field tag string
Offset uintptr // offset within struct, in bytes
Index []int // index sequence for Type.FieldByIndex
Anonymous bool // is an embedded field
}
可以看出Tag也是字段的一个组成部分.Tag的类型为StructTag.实际上string类型的一个别名.如下所示.
type StructTag string
3.1.2Tag约定:
Tag本身是一个字符串.从单语义上讲.任意的字符串都是合法的.但有一个约定的格式.那就是key:value.
key:必须是非空字符串.字符串不能包含控制符 空格 引号 冒号.
value:以双引号标记的字符串.
注:key和value之间使用冒号分隔.冒号前后不能有空格,多个key:value之间由空格分开.
3.1.3获取Tag:
func main() {
t := TypeMeta{}
mType := reflect.TypeOf(t)
for i := 0; i < mType.NumField(); i++ {
fmt.Printf("Field name %s,Tag:%s\n", mType.Field(i).Name, mType.Field(i).Tag.Get("json"))
}
}
3.1.4Tag的意义:
Go语言的反射特性可以动态的给结构体成员赋值.正式因为有Tag.在赋值前可以使用
Tag来决定赋值的动作.
悠然见南山.
如果大家喜欢我的分享的话.可以关注我的微信公众号
念何架构之路