二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Shell编程

  • Go编程笔记

  • 前端编程笔记

  • Go学习笔记

    • 基础部分

      • 基础知识
      • 数据类型
      • fmt的格式化输入输出
      • 运算符
      • 流程控制
      • 认识函数
      • 包的操作
      • 项目工程-在同级目录
      • 指针(pointer)
      • 数组(array)
      • 切片(slice)
      • 字典(map)
      • 结构体(struct)
      • 匿名组合
        • 1,匿名字段。
        • 2,匿名字段初始化。
        • 3,成员的操作。
        • 4,同名字段。
        • 5,非结构体匿名字段。
        • 6,结构体指针类型匿名字段。
      • 方法
      • 接口
      • error接口
      • panic
      • recover
      • 字符串操作
      • 字符串转换
      • 正则表达式
      • JSON处理
      • 文件的操作
      • goroutine
      • channel
      • select
      • sync-lock锁
      • 网络概述
      • Socket编程
      • 发文件与聊天室
      • http编程
      • 爬虫实战
      • 单元测试了解
    • web框架

    • orm框架

  • Vue-21年学习笔记

  • Vue-22年重学笔记

  • 编程世界
  • Go学习笔记
  • 基础部分
二丫讲梵
2021-07-10
目录

匿名组合

文章发布较早,内容可能过时,阅读注意甄别。

对于面向对象变成的支持,Go 语言设计的非常简洁且优雅。因为,Go 语言并没有沿袭传统面向对象编程中的诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继承),虚函数,构造函数和析构函数,隐藏的 this 指针等。

传统面向对象核心概念可如图了解:

m_2ab287133a302b022f5eaf17ba39d3cb_r

尽管 Go 语言中没有封装,继承,多态这些概念,但同样通过别的方式实现了这些特性:

  • 封装:通过方法实现
  • 继承:通过匿名字段实现
  • 多态:通过接口实现

一般情况下,定义结构体的时候是字段名与其类型一一对应,实际上 Go 支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。

当匿名字段也是一个结构体的时候,那么这个结构体所拥有的全部字段都被隐式地引入了当前定义的这个结构体。

# 1,匿名字段。

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	//内容重叠的,可以直接引用,只有类型,没有名字,就是匿名字段
	//这样Student就会继承Person这个结构体里边的成员了
	Person
	id   int
	addr string
}

func main() {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 2,匿名字段初始化。

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	//内容重叠的,可以直接引用,只有类型,没有名字,就是匿名字段
	//这样Student就会继承Person这个结构体里边的成员了
	Person
	id   int
	addr string
}

func main() {
	//顺序初始化
	var s1 = Student{Person{"yoyo", 'm', 18}, 1, "hangzhou"}
	fmt.Println("s1 = ", s1)

	//自动推导类型
	s2 := Student{Person{"yoyo", 'm', 18}, 1, "hangzhou"}
	//fmt.Println("s2 = ", s2)
	//%+v显示详细信息
	fmt.Printf("s2 = %+v\n", s2)

	//指定成员初始化,没有初始化的默认为0
	s3 := Student{addr: "hangzhou"}
	fmt.Printf("s3 = %+v\n", s3)

	s4 := Student{Person: Person{age: 18}, addr: "hangzhou"}
	fmt.Printf("s4 = %+v\n", s4)

	//s5 := Student{age: 18, addr: "hangzhou"} //err
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 3,成员的操作。

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	Person
	id   int
	addr string
}

func main() {

	s1 := Student{Person{"yoyo", 'm', 18}, 1, "hangzhou"}
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)
	//修改某个成员的值
	s1.name = "eryajf"
	s1.age = 22
	s1.id = 5
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)

	//修改Person里边的值
	s1.Person = Person{"long", 'b', 20}
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 4,同名字段。

其规则与前边的同名变量时一致的。

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	Person
	id   int
	addr string
	name string
}

func main() {
	//定义一个变量
	var s Student
	//如果定义的结构体引用的匿名字段有重名字段,那么在字段赋值的时候
	//默认规则为就近原则,如果就近没有,再往外层匹配
	s.name = "erya" //这个name是给Student赋值
	s.sex = 'm'
	s.age = 18
	s.addr = "hangzhou"
	fmt.Printf("s = %+v\n", s)

	//如果要给Person里边的name字段赋值,则需要显式调用
	s.Person.name = "long"
	fmt.Printf("s = %+v\n", s)

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 5,非结构体匿名字段。

package main

import "fmt"

type mystr string //自定义类型,相当于别名

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	Person //结构体类型匿名字段
	int    //基础类型匿名字段
	mystr
}

func main() {
	s := Student{Person{"yoyo", 'm', 18}, 666, "hangzhou"}
	fmt.Printf("s = %+v\n", s)

	s.Person = Person{"erya", 'm', 22}
	fmt.Println(s.Person, s.int, s.mystr)

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 6,结构体指针类型匿名字段。

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	*Person //指针类型
	id      int
	addr    string
}

func main() {

	s1 := Student{&Person{"yoyo", 'm', 18}, 1, "hangzhou"}
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)

	//通过new操作
	var s2 Student
	s2.Person = new(Person)
	s2.name = "eryajf"
	s2.age = 22
	s2.id = 5
	fmt.Println(s2.name, s2.sex, s2.age, s2.id, s2.addr)

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
微信 支付宝
#go
上次更新: 2024/07/04, 22:40:37
结构体(struct)
方法

← 结构体(struct) 方法→

最近更新
01
记录二五年五一之短暂回归家庭
05-09
02
学习周刊-总第210期-2025年第19周
05-09
03
学习周刊-总第209期-2025年第18周
05-03
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式