Go数据-结构体(五)
2019-08-02 本文已影响0人
草莓君_
结构体
结构体(struct)将多个不同类型命名字段(field)序列打包成一个复合类型。
- 字段名必须唯一
- 可用“_”补位
- 支持使用自身指针类型成员
- 字段名、排列顺序属于类型组成部分。
type node struct {
_ int
id int
next *node
}
func main() {
n1 := node{
id: 1,
}
n2 := node{
id: 2,
next: &n1,
}
fmt.Println(n1, n2)
}
可按顺序初始化全部字段,或使用命名方式初始化指定字段
func main() {
type user struct {
name string
age int
}
u1 := user{"Tom", 12}
u2 := user{"tome"} //编译报错too few values in user literal
}
可直接定义匿名结构类型变量,或用作字段类型。但因其缺少类型标识,在作为字段类型时无法直接初始化。
func main() {
u := struct {
name string
age int
}{
name: "Tom",
age: 19,
}
type file struct {
name string
attr struct{
owner int
perm int
}
}
f := file{
name: "test.dat",
//attr: { //错误missing type in composite literal
// owner: 1,
// perm: 0121,
//},
}
f.attr.owner = 1 //正确方式
f.attr.perm = 2
fmt.Println(u, f)
}
只有在所有字段类型全部支持时,才可能做相等操作。
func main() {
type data struct {
x int
y map[string]int
}
d1 := data{
x: 1,
}
d2 := data{
x: 1,
}
println(d1 == d2) //无效操作struct containing map[string]int cannot be compared
}
可使用指针直接操作结构字段,但不能时多级指针。
func main() {
type user struct {
name string
age int
}
p := &user{
name: "Tom",
age: 19,
}
p.name = "Mary"
p.age++
}
空结构
空结构(struct{}
)是指没有字段的结构类型。他比较特殊,因为无论是其自身,还是作为数组元素类型,其长度都为零。
func main() {
var a struct{}
var b [100]struct{}
println(unsafe.Sizeof(a),unsafe.Sizeof(b))
}
输出: 0 0
尽管没有分配数组内存,但依然可以操作元素,对应切片len、cap属性也正常。
func main() {
var d [100]struct{}
s := d[:]
d[1] = struct{}{}
d[2] = struct{}{}
fmt.Println(s[3], len(s), cap(s))
}
输出:
{} 100 100
匿名字段
所谓匿名字段,是指没有名字,仅有类型的字段,也被称作嵌入字段或嵌入类型。
type attr struct {
perm int
}
type file struct {
name string
attr //仅有类型名
}
不能将基础类型和其指针类型同时嵌入,因为两者隐式名字相同。
type data struct {
*int
int //错误 duplicate field int
}
虽然可以像普通字段那样访问匿名字段成员,但会存在重名问题。默认情况下,编译器从当前显式命名字段开始,逐步向内查找匿名字段成员。如匿名字段成员被外层同名字段遮蔽,那么必须使用显式字段名。
func main() {
d := data{
name: "data",
file: file{"file"},
}
d.name = "data2" //当问data.name
d.file.name = "file2" //使用显式字段名访问 data.file.name
fmt.Println(d.name, d.file.name)
}