什么是结构体嵌套

一个结构体中可以嵌套包含另一个结构体或结构体指针

结构体嵌套

package main

import "fmt"

// 桌子结构体
type table struct {
	material string
	shape int
	com common // 嵌套结构体
}

// 被嵌套的结构体定义
type common struct {
	year int
}

func main() {
	// 嵌套结构体定义和输出方法
	s1 := table{
		material: "木头",
		shape: 5,
		com: common{
			year: 2000,
		},
	}
	fmt.Println(s1.com.year)
}

匿名结构体嵌套

package main

import "fmt"

// 狗结构体
type dog struct {
	name string
	varieties string
	common // 嵌套匿名结构体
}

// 被嵌套的结构体定义
type common struct {
	year int
}

func main() {
	// 匿名嵌套结构体定义和输出方法
	s2 := dog{
		name:      "布迪",
		varieties: "柴犬",
		common: common{
			year: 2019,
		},
	}
	fmt.Println(s2.year) // 直接输出
	fmt.Println(s2.common.year) // 寻址输出
}

当访问结构体成员时会先在结构体中查找该字段,找不到再去嵌套的匿名字段中查找。

嵌套结构体的字段名冲突

嵌套结构体内部可能存在相同的字段名。在这种情况下为了避免歧义需要通过指定具体的内嵌结构体字段名。

//Address 地址结构体
type Address struct {
	Province   string
	City       string
	CreateTime string
}

//Email 邮箱结构体
type Email struct {
	Account    string
	CreateTime string
}

//User 用户结构体
type User struct {
	Name   string
	Gender string
	Address
	Email
}

func main() {
	var user3 User
	user3.Name = "沙河娜扎"
	user3.Gender = "男"
	// user3.CreateTime = "2019" //ambiguous selector user3.CreateTime
	user3.Address.CreateTime = "2000" //指定Address结构体中的CreateTime
	user3.Email.CreateTime = "2000"   //指定Email结构体中的CreateTime
}

用结构体嵌套模拟实现“继承”

继承

例子解释:

zoozoorundogzoodogfoot
dogzoo

代码示例

package main

import "fmt"

// 动物园结构体
type zoo struct {
	name string
}
// zoo 的 run 方法
func (z *zoo) run()  {
	fmt.Printf("这个动物的名字叫:%s \n", z.name)
}

// 狗结构体
type dog struct {
	footer int
	zoo
}
// dog 的 foot 方法
func (d *dog) foot()  {
	fmt.Printf("这个狗有 %d 条腿 \n", d.footer)
}

func main() {
	s1 := &dog{
		footer: 4,
		zoo: zoo{name: "布迪"},
	}
	fmt.Println(s1)
	s1.run()
	s1.foot()
}
&{4 {布迪}}
这个动物的名字叫:布迪
这个狗有 4 条腿