结构体就是一个复杂的数据类型,里面可以包含字段,也可以嵌套其他结构体
Go 中没有 class,可以使用 struct 代替
声明
通过 type she
type struct_name struct {
field_name1 field_type1
field_name2 field_type2
}
示例:
type student struct {
Name string
Age int
score int
}
定义
var stu student
var stu *student = new(student)
var stu *student = &student{}
访问
通过 .
可以访问到结构体内的字段
指向结构体的指针也可以直接访问
(*struct_name).field_name == struct_name.field_name
储存结构
结构体内部储存的数据在内存中都是连续的
tag
由于 Go 中限制只有以大写字母开头的才能在其他包中访问到
可以通过 tag
使得指定包中获取到的名称
示例:
// 小写字母开头的无法在其他包中访问
type student1 struct {
Name string
Age int
score int
}
// 设置 tag 使得 json 包中访问数据可以自定义
type student2 struct {
Name string `json:"name"`
Age int `json:"age"`
Score int `json:"score"`
}
func jsonTest() {
stu1 := student1{
Name: "Tom",
Age: 18,
score: 90,
}
stu2 := student2{
Name: "Tom",
Age: 18,
Score: 90,
}
res, err := json.Marshal(stu1)
if err != nil {
fmt.Printf("some error occured: %v", err)
} else {
fmt.Printf("student1: %s
", string(res))
}
res, err = json.Marshal(stu2)
if err != nil {
fmt.Printf("some error occured: %v", err)
} else {
fmt.Printf("student2: %s
", string(res))
}
}
输出结果:
student1: {"Name":"Tom","Age":18}
student2: {"name":"Tom","age":18,"score":90}
匿名字段
定义结构体时,可以省略字段名只写类型,这样就定义了一个匿名字段
由于结构体中字段名必须时唯一的,所以匿名的类型也必须是唯一的
示例:
type foo struct {
field1 int
string
}
func main() {
bar := foo{}
bar.field1 = 1
bar.string = "hello world"
fmt.Printf("%v", bar)
}
结构体嵌套
在结构体中嵌套结构体时使用匿名字段可以更加简便获取内层结构体的字段
当 内层结构体的字段 和 外层结构体的字段 没有重复时可以直接获取,如果有重复时需要加上 内层结构体名 才能正常获取
这就是 Go 实现继承的方式
匿名字段访问示例:
type foo struct {
field1 int
field2 string
}
type bar struct {
foo
field1 string
field3 int
}
func main() {
foobar := bar{}
foobar.foo.field1 = 1
foobar.field2 = "hello"
foobar.field1 = "world"
foobar.field3 = 2
fmt.Printf("%v", foobar)
}
输出结果:
{{1 hello} world 2}
如果没有使用匿名字段,这时就是组合,即使 内层结构体的字段 和 外层结构体的字段 没有重复时也不能省略结构体名
组合
组合和嵌套匿名结构体相似,但是结构体名称不能省略