golang之结构体结构体嵌入和匿名成员
2024-08-26 17:28:42
考虑一个二维的绘图程序,提供了一个各种图形的库,例如矩形、椭圆形、星形和轮形等几何形状。这里是其中两个的定义:
type Circle struct {
X, Y, Radius int
}
type Wheel struct {
X, Y, Radius, Spokes int
}
一个Circle代表的圆形类型包含了标准圆心的X和Y坐标信息,和一个Radius表示的半径信息。一个Wheel轮形除了包含Circle类型所有的全部成员外,还增加了Spokes表示径向辐条的数量。我们可以这样创建一个wheel变量:
var w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20
随着库中几何形状数量的增多,我们一定会注意到它们之间的相似和重复之处,所以我们可能为了便于维护而将相同的属性独立出来:
ype Point struct {
X, Y int
}
type Circle struct {
Center Point
Radius int
}
type Wheel struct {
Circle Circle
Spokes int
}
这样改动之后结构体类型变的清晰了,但是这种修改同时也导致了访问每个成员变得繁琐:
var w Wheel
w.Circle.Center.X = 8
w.Circle.Center.Y = 8
w.Circle.Radius = 5
w.Spokes = 20
Go语言有一个特性让我们只声明一个成员对应的数据类型而不指名成员的名字;这类成员就叫匿名成员。匿名成员的数据类型必须是命名的类型或指向一个命名的类型的指针。下面的代码中,Circle和Wheel各自都有一个匿名成员。我们可以说Point类型被嵌入到了Circle结构体,同时Circle类型被嵌入到了Wheel结构体。
type Circle struct {
oint
Radius int
}
type Wheel struct {
Circle
Spokes int
}
得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:
var w Wheel
w.X = 8 // equivalent to w.Circle.Point.X = 8
w.Y = 8 // equivalent to w.Circle.Point.Y = 8
w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20
在右边的注释中给出的显式形式访问这些叶子成员的语法依然有效,因此匿名成员并不是真的无法访问了。其中匿名成员Circle和Point都有自己的名字——就是命名的类型名字——但是这些名字在点操作符中是可选的。我们在访问子成员的时候可以忽略任何匿名成员部分。
不幸的是,结构体字面值并没有简短表示匿名成员的语法, 因此下面的语句都不能编译通过:
w = Wheel{8, 8, 5, 20} // compile error: unknown fields
w = Wheel{X: 8, Y: 8, Radius: 5, Spokes: 20} // compile error: unknown fields
结构体字面值必须遵循形状类型声明时的结构,所以我们只能用下面的两种语法,它们彼此是等价的:
w = Wheel{Circle{Point{8, 8}, 5}, 20}
w = Wheel{
Circle: Circle{
Point: Point{X:8, Y:8},
Radius: 5,
},
Spokes: 20,
}
最新文章
- Git - 问题集
- 制作dll自动注册工具
- ng-switch 指令
- rndc控制远程dns服务器配置方法
- CSS行高--line-height
- 【17】以独立语句将newed对象置入智能指针
- UEditor配置图片上传
- 机器学习算法库scikit-learn的安装
- 适用于 PHP 开发人员的 Python 基础知识
- secedit
- 解决axios传递参数后台无法接收问题
- 将Session放入Redis
- mysql一列相同另一列相加
- Java -- POI -- 入门使用以及简单介绍
- asm.js 和 Emscripten 入门教程
- HTTP请求属性说明
- static link:关于gcc连接静态库的几种方式
- 程序bug导致了天大的损失,要枪毙程序猿吗?[ZZ]
- c#代码获取web.config配置文件里面设置的 <;compilation debug=";true";节点
- vue 组件 单选切换控制模板 v-bind-is
热门文章
- Java 面向对象(十六)
- Mininet系列实验(七):Mininet脚本实现控制交换机行为
- C/C++/Linux编程经典电子书pdf下载
- git commit之后,撤销 commit
- Docs-.NET-C#-指南-语言参考-预处理器指令:#region(C# 参考)
- Gradle基础:11:使用Kotlin的Gradle(转)
- PHP 小程序发模板消息
- 泡泡一分钟:FMD Stereo SLAM: Fusing MVG and Direct Formulation Towards Accurate and Fast Stereo SLAM
- 为什么NtReadVirtualMemory 硬件断点无法下断
- Django架站的16堂課