golang中的struct

XITEHIP · · 1023 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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

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。

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"))

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

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表)这个字符串。

3 总结

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

参考go语言圣经


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:XITEHIP

查看原文:golang中的struct

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1023 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传