golang中的struct

结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体,每一个值称为结构体的成员。下面分两方面介绍:一个是基础部分,一个是看一下结构体在实际内存中的内存模型。golang

1 基础

1.1 定义

  • type structName typeName {} ###1.2 声明
  • var varName structName ###1.3 初始化
  • type Point struct{ X, Y int } p := Point{1, 2}
  • anim := gif.GIF{LoopCount: nframes} 此建立方式结构体成员顺序不重要。 ###1.4 new
  • new(structType)
  • new出来的是结构体指针。

1.5 特性

  • 结构体成员相同,顺序不一样不是相同结构体类型。
  • 结构体成员以大写字母能够导出,小写的不能够导出。
  • 结构体类型不能再包含形同类型的成员:由于一个聚合的值不能包含它自身。但结构体能够包含相同类型的指针类型的成员,这可让咱们建立递归的数据结构,好比链表和树结构等。
  • 结构体类型的零值对应的是每一个成员相应类型的零值。
  • 若是结构体没有任何成员的话就是空结构体,写做struct{}。它的大小为0,也不包含任何信息,可是有时候依然是有价值的。好比在管道中传递的数据若是只紧起到信号做用那彻底能够用struct{}以便节省空间。

1.6 函数传参

  • 值传递,若是结构体比较大的话最好指针传递。

1.7 结构体比较

  • 若是结构体的所有成员都是能够比较的,那么结构体也是能够比较的,那样的话两个结构体 将可使用==或!=运算符进行比较。

1.8 匿名成员

  • 只声明一个成员对应的数据类型而不指名成员的名字,这类成员就叫匿名成员。
  • 由于匿名成员也有一个隐式的名字,所以不能同时包含两个类型相同的匿名成员,这会致使 名字冲突。

1.9 嵌套

结构体能够嵌套另外一个结构体。 结构体能够包含结构体类型的匿名成员,这样能够经过p.b就能够访问匿名成员结构体中的b。json

1.10 标签

1.10.1 标签主要应用于json字符串与结构体成员的相互转换的映射关系,见下方代码实例:
type User struct {
    UserId   int    `json:"user_id"`
    UserName string `json:"user_name"`
}

u := &User{UserId: 1, UserName: "xitehip"}
j, _ := json.Marshal(u)
fmt.Println(string(j))
// 输出内容:{"user_id":1,"user_name":"tony"}
复制代码
1.10.2 struct成员变量标签获取
t := reflect.TypeOf(u)
field := t.Elem().Field(0)
fmt.Println(field.Tag.Get("json"))
复制代码

关于映射后续会有专门章节讲解。bash

2 内存布局

代码实例:数据结构

type Person struct {
	age int
	class int
	name string
}
var pp *Person
func main() {
	p := Person{age:18, class:8, name:"xitehip"}
	pp = &p
	fmt.Println(*pp)
}
复制代码

编译生成的可执行文件,而后用gdb去分析内存布局见下图1 函数

图1

由图1能够发现,结构体中的元素确实是连续排布的,只不过成员name存储的是指针。打印name指针的值发现确实是xitehip(可查看ascii表)这个字符串。oop

3 总结

结构体是一种存储复合数据,主要应用于一个实体有多个数据类型的场景。在golang面向对象思想中,结构体也应用很是普遍,在后续的文章会详细讲解golang中的面向对象。布局

参考go语言圣经ui

相关文章
相关标签/搜索