Go 匿名字段学习总结

2,450 阅读2分钟

前言

  • Go 中,没有传统面向对象的写法,所以要想实现 extends 类似功能,就得使用 匿名字段
  • 下面就一起来看看匿名字段的几种使用方式和细节

案例

第一种方式

package main

import "fmt"

type Walk struct {
	Speed float64
}

type Person struct {
	Name string
	Age int
	Walk
}

func main() {
	p1 := Person{
		Name: "张三",
		Age: 23,
		Walk: Walk{
			Speed: 10,
		},
	}
	fmt.Printf("%#v\n", p1)
	fmt.Println("直接访问速度字段", p1.Speed) // 输出 10,当前结构体没有 Speed 会自动查找匿名结构体字段
	fmt.Println("通过匿名字段访问速度", p1.Walk.Speed) // 输出 10,访问匿名字段 Speed 字段
}

第二种方式

package main

import "fmt"

type Walk struct {
	Speed float64
}

type Person struct {
	Name string
	Age int
	Speed int
	Walk
}

func main() {
	p1 := Person{
		Name: "张三",
		Age: 23,
		Walk: Walk{
			Speed: 10,
		},
	}
	fmt.Printf("%#v\n", p1)
	fmt.Println("直接访问速度字段", p1.Speed) // 输出 0,当前结构体存在 Speed,不会继续查找匿名字段
	fmt.Println("通过匿名字段访问速度", p1.Walk.Speed) // 输出 10,访问匿名字段 Speed 字段
}

第三种方式

package main

import "fmt"

type Walk struct {
	Speed float64
}

type Run struct {
	Speed float64
}

type Person struct {
	Name string
	Age int
	Walk
	Run
}

func main() {
	p1 := Person{
		Name: "张三",
		Age: 23,
		Walk: Walk{
			Speed: 10,
		},
		Run: Run{
			Speed: 20,
		},
	}
	fmt.Printf("%#v\n", p1)
	//fmt.Println("直接访问速度字段", p1.Speed) // 报错,因为 Person 结构体本身不存在 Speed 字段,但是存在两个匿名体,无法自动选择
	fmt.Println("通过匿名字段访问速度", p1.Walk.Speed) // 输出 10,访问匿名字段 Speed 字段
	fmt.Println("通过匿名字段访问速度", p1.Run.Speed) // 输出 10,访问匿名字段 Speed 字段
}

总结

  • 结构体字段访问顺序 当前结构体 -> 匿名字段
  • 当前结构体不存在字段,但是有两个匿名字段,则需要通过具体路径访问

Ps: 学习路上,希望大佬指正
2020年05月25日17:49:03