结构
Go 中的struct
与 C 中的 struct
非常相似,并且 Go 没有 class 。使用 type<Name> struct{}
定义结构,名称遵循可见性规则。
- 支持指向自身的指针类型成员
- 支持匿名结构,可用作成员或定义成员变量
- 匿名结构也可以用于
map
的值 - 可以使用字面值对结构进行初始化
- 运行直接通过指针来读写结构成员
- 相同类型的成员可进行直接拷贝赋值
- 支持
==
与!=
比较运算符,但是不支持>
和<
- 支持匿名字段,本质上是定于了以某个类型名为名称的字段
- 嵌入结构作为匿名字段看起来像继承,但不是继承
- 可使用匿名字段指针
1 | type person struct { |
输出
1 | {Amy 18 112340259} |
操作
类似像JavaScript中对象属性的操作
1 | func main() { |
输出
1 | {Amy 22 112340259} |
值拷贝
作为函数的参数时,是一个值拷贝,而不是引用类型
1 | func structTest1(a person) { |
输出
1 | {Amy 22 112340259} |
可以发现age
在函数执行后并没有发生改变。如果需要改变,需要传递指针(地址)
1 | + func structTest1(a *person) { |
输出
1 | {Amy 22 112340259} |
指向结构的指针
在初始化时,变成结构的指针,也可以达到上面的效果。
1 | - amy := person{"Amy", 18, 112340259} |
在对一个结构进行初始化时,习惯性使用取地址符号&
,变量就变成指向某个结构的指针,方便在下面编码过程中特地去获取地址。且也可以直接对结构中的属性直接进行操作
匿名结构
没定义结构的名称,临时声明了一个结构,并对字面值进行了初始化
1 | dog := &struct { |
输出
1 | &{white long} |
结构体中
1 | type person struct { |
输出
1 | &{amy 18 {123 china}} |
匿名字段
在结构体中未声明属性名
1 | type pet struct { |
输出
1 | &{dog 2} |
如果此时交换初始化参数的位置,会发生错误
1 | - a := &pet{"dog", 2} |
输出
1 | # command-line-arguments |
类型比较操作
同类型之间的可以进行比较,作==
和!=
,不能作>
或者<
1 | a := pet{name: "Amy", age: 18} |
输出
1 | true |
如果内容一致,但是类型不一样
1 | a := pet{name: "Amy", age: 18} |
输出
1 | # command-line-arguments |
嵌入struct
1 | type human struct { |
输出
1 | {{A 12 1} english} {{aa 2 0} 2002} |
练习
如果匿名字段和外层结构有同名字段,应该如何进行操作
1 | type basePo struct { |
输出
1 | 1 2 |
bizBasePo
与basePo
存在同名字段
1 | bill := bizBasePo{id: "1", basePo: basePo{id: "2"}} |
输出
1 | 3 2 |
如果直接改成这样
1 | type basePo struct { |
输出
1 | 2 2 |
如果是多个同名
1 | type basePo struct { |
输出
1 | # command-line-arguments |
编译错误,此时使用那个嵌入体中的字段
可以改成这样
1 | type basePo struct { |