Golang 匿名字段
定义一个struct,定义的时候是字段名与其类型一一对应,实际上Go语言支持只提供类型,而不写字段名的方式,也就是匿名字段,或称为嵌入字段。
当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段以及方法(指绑定在这个类型上的,见最后)都被隐式地引入了当前定义的这个struct。
让我们来看一个例子,让上面说的这些更具体化。
package mainimport "fmt"type Human struct {name stringage intweight int}type Student struct {Human // 匿名字段,那么默认Student就包含了Human的所有字段speciality string}func main() {// 我们初始化一个学生mark := Student{Human{"Mark", 25, 120}, "Computer Science"}// 我们访问相应的字段fmt.Println("His name is ", mark.name)fmt.Println("His age is ", mark.age)fmt.Println("His weight is ", mark.weight)fmt.Println("His speciality is ", mark.speciality)// 修改对应的备注信息mark.speciality = "AI"fmt.Println("Mark changed his speciality")fmt.Println("His speciality is ", mark.speciality)// 修改他的年龄信息fmt.Println("Mark become old")mark.age = 46fmt.Println("His age is", mark.age)// 修改他的体重信息fmt.Println("Mark is not an athlet anymore")mark.weight += 60fmt.Println("His weight is", mark.weight)}
图2.7 Student和Human的方法继承的内存结构
我们看到Student访问属性age和name的时候,就像访问自己所有用的字段一样,对,匿名字段就是这样,能够实现字段的继承。是不是很酷?还有比这个更酷的呢!那就是student还能访问Human这个字段作为字段名,请看下面的代码。
mark.Human = Human{"Marcus", 55, 220}mark.Human.age -= 1
通过匿名访问和修改字段很有用,但不仅仅是struct字段,所有的内置类型和自定义类型都可以作为匿名字段。请看下面的例子。
package mainimport "fmt"type Skills []stringtype Human struct {name stringage intweight int}type Student struct {Human // 匿名字段,structSkills // 匿名字段,自定义的类型string sliceint // 内置类型作为匿名字段speciality string}func main() {// 初始化学生Janejane := Student{Human:Human{"Jane", 35, 100}, speciality:"Biology"}// 现在我们来访问相应的字段fmt.Println("Her name is ", jane.name)fmt.Println("Her age is ", jane.age)fmt.Println("Her weight is ", jane.weight)fmt.Println("Her speciality is ", jane.speciality)// 我们来修改他的skill技能字段jane.Skills = []string{"anatomy"}fmt.Println("Her skills are ", jane.Skills)fmt.Println("She acquired two new ones ")jane.Skills = append(jane.Skills, "physics", "golang")fmt.Println("Her skills now are ", jane.Skills)// 修改匿名内置类型字段jane.int = 3fmt.Println("Her preferred number is", jane.int)}
从上面例子可见,struct不仅能将struct作为匿名字段,自定义类型、内置类型都可以作为匿名字段,而且可以在相应的字段上进行函数操作(如例子中的append)。
有个问题:如果human里面有一个字段叫做phone,而student也有一个字段叫做phone,那么该怎么办呢?
Go语言很简单地解决了这个问题,最外层的优先访问,也就是当你通过student.phone访问的时候,是访问student里面的字段,而不是human里面的字段。
这样就允许我们去重载通过匿名字段继承的一些字段,当然如果我们想访问重载后对应匿名类型里面的字段,可以通过匿名字段名来访问。请看下面的例子。
package mainimport "fmt"type Human struct {name stringage intphone string // Human类型拥有的字段}type Employee struct {Human // 匿名字段Humanspeciality stringphone string // 雇员的phone字段}func main() {Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}fmt.Println("Bob's work phone is:", Bob.phone)// 如果我们要访问Human的phone字段fmt.Println("Bob's personal phone is:", Bob.Human.phone)}
关于对方法的继承,看一段的代码对比就比较明了了:
package mainimport ("fmt" )type Animal struct {Age int }type Person struct {AnimalSex int}func (animal Animal) getName() string {return "animal" }// func (person Person) getName() string { // return "person" // }func main() {var animal Animalvar person Personfmt.Println(animal.getName())fmt.Println(person.getName()) } // 输出 // animal // animal
package mainimport ("fmt" )type Animal struct {Age int }type Person struct {AnimalSex int}func (animal Animal) getName() string {return "animal" }func (person Person) getName() string {return "person" }func main() {var animal Animalvar person Personfmt.Println(animal.getName())fmt.Println(person.getName()) } // 输出 // animal // persion
最后,如果匿名字段是指针的话,那么只是占一个指针的大小:
package main import "fmt" import "unsafe"type T struct {a intb float64 }type A struct{T }type B struct{*T }func main() {var t Tvar a Avar b Bfmt.Println(unsafe.Sizeof(t))fmt.Println(unsafe.Sizeof(a))fmt.Println(unsafe.Sizeof(b))var x *Tfmt.Println(unsafe.Sizeof(x)) } // 输出: // 16 // 16 // 8 // 8
转载于:https://www.cnblogs.com/maji233/p/11059589.html
Golang 匿名字段相关推荐
- GoLang之结构体匿名字段
文章目录 1.结构体内嵌套匿名结构体(访问相同字段) 2.结构体内嵌套匿名结构体(访问相同方法) 3.结构体嵌套匿名自定义类型 4.结构体嵌套匿名内置类型 5.结构体嵌套任意类型匿名指针 6.匿名结构 ...
- GO学习笔记:struct的匿名字段
我们上面介绍了如何定义一个struct,定义的时候是字段名与其类型一一对应,实际上Go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段. 当匿名字段是一个struct的时候,那么这个 ...
- golang匿名组合
匿名组合 匿名字段 一般情况下,定义结构体的时候是字段名和其类型一一对应,实际上go支持只提供类型而不写字段名的方法,也就是匿名字段,也称为嵌入式字段 当匿名字段也是一个结构体的时候,那么这个结构体所 ...
- 兄弟连go教程(19)数据 - 匿名字段
匿名字段不过是⼀一种语法糖,从根本上说,就是⼀一个与成员类型同名 (不含包名) 的字段. 被匿名嵌⼊入的可以是任何类型,当然也包括指针. type User struct { name string ...
- Golang 匿名结构体及测试代码编写技巧
转自: https://www.jianshu.com/p/901820e17ffb 结构体基础 结构体 (struct) 将多个不同类型的字段集中组成一种复合类型,按声明时的字段顺序初始化. typ ...
- golang匿名函数
文章目录 1. 匿名函数的声明 2. 匿名函数的作用 2.1 在定义时调用匿名函数 2.2 匿名函数可以赋值 2.3 匿名函数作为回调函数 2.4 使用匿名函数实现操作封装 3. 总结 1. 匿名函数 ...
- Golang匿名结构体结构体嵌套(实战使用)
背景 最近研究钉钉机器人的时候,总是会向钉钉官方接口发送很多请求,发送请求的时候,需要封装body结构体传递参数,还要封装response结构体用来接收返回值,有时候,response结构体中还要嵌套 ...
- 四、golang类型讲解--go语言学习笔记
擅自使用了七牛大牛们的PPT资料,希望不要怪罪,这里谢谢大牛们的分享. 映射 map 一个"键-值"对 关键点:注意并发读写情况,上锁 不能对未初始化的 map 进行写,会抛异常( ...
- golang 结构体简介
Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型.试图表示一个现实世界中的实体. 结构体由一系列命名的元素组成,这些元素又被称为字段,每个字段都有一个名称和 ...
最新文章
- JSIS3D:具有多任务点向网络和多值条件随机场的3D点云联合语义-实例分割
- TC264信标组 双车组 资源规划 库函数示例
- 快手,字节面试题,将IP地址转换成整数类型,再转换回来。C++代码
- think in java - 第四章 学习笔记
- pytorchyolov4训练_使用pytorch-yolov5 訓練自己的數據集-2020.6.15
- c语言风景日历制作系统,初学,C语言日历制作
- PHP经验——获得PHP版本信息及版本比较
- 关于redis说法正确的是_还不会正确使用Redis?这几个技巧让你的程序快如闪电...
- Spyder5.3.3无法使用下载好的库
- 印象笔记导入html笔记,Evernote Importer|印象笔记导入
- 可以在手机预览ps设计稿的软件
- 使用uiautomation 实现微信自动发送消息
- 批处理中 %~d0 cd %~dp0 的含义
- 用DEV-C++制作狼人杀
- 第五章第五题(千克与磅之间的互换)(Conversion from kilogram to pound and pound to kilogram)
- 双活数据中心架构分析及优缺点
- Python+Vue计算机毕业设计教师教学质量评价管理2lbw7(程序+LW+源码+部署)
- 从技术小白到收获BAT研发offer,分享我的学习经验和感悟(赠送相关学习资料)
- java调用kettle自定义kettle.properties配置文件路径
- 计算机不接受跨专业考研,2016跨专业考研需谨慎的专业解读:计算机
热门文章
- Java Web项目实战案例一
- 虚拟服务器安装管理工具,easypanel虚拟主机管理面板v1.9.2安装版-虚拟主机管理软件...
- Java使用Aspose组件进行多文档间的转换操作
- 下载安装及编写第一个C语言程序Visual Studio 2019
- 数据库 主键 外键 唯一键区别
- GnuTLS recv error (-54): Error in the pull function.
- RIP原理、毒性反转原理与应用【eNSP实现】
- 单片机+DHT11的温湿度采集监测系统,LCD1602显示,带报警功能,C代码、原理图和Proteus仿真
- 命令行运行Unity脚本
- 2021年中国电视节目产量、播出时间及电视节目综合人口覆盖率分析[图]