介绍

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体是值类型

image.png

定义结构体

字段可以是 基本数据类型、数组、引用数据类型
字段类型默认值:指针、slice、map的零值都是nil,即还没有分配空间

  1. type 结构体名称 struct {
  2. field1 type
  3. field2 type
  4. ...
  5. }

使用

  1. package main
  2. import "fmt"
  3. func main() {
  4. // 定义结构体
  5. type Cat struct {
  6. Name string
  7. Age int
  8. Color string
  9. }
  10. // 使用
  11. var cat1 Cat // 像使用其它变量一样
  12. cat1.Name = "小白"
  13. cat1.Age = 3
  14. cat1.Color = "白色"
  15. fmt.Println("cat1 = ", cat1) // {小白 3 白色}
  16. }

结构体和结构体变量的区别和联系

  1. 结构体是自定义的数据类型,代表一类事物。 Cat
  2. 结构体变量(实例)是具体的,实际的,代表一个具体变量。 cat1

    内存探究

    image.png

    引用类型字段使用注意

  3. 指针、slice、map的零值都是nil

  4. slice、map类型的字段,使用赋值的时候要先make,分配内存空间
  5. 不同结构体变量的字段是独立的,互不影响。(结构体是值类型) ```bash package main

import “fmt”

// 字段类型默认值:指针、slice、map的零值都是nil,即还没有分配空间 type Person struct { Name string Age int Score float64 Ptr *int Slice []int Map map[string]string }

type Monster struct { Name string Age int }

func main() { var p1 Person fmt.Println(“p1 = “, p1) // { 0 0 [] map[]} fmt.Println(“p1.Ptr == nil”, p1.Ptr == nil) // true fmt.Println(“p1.Slice == nil”, p1.Slice == nil) // true fmt.Println(“p1.Map == nil”, p1.Map == nil) // true

// p1.Slice[0] = 100 // panic: runtime error: index out of range [0] with length 0 // 使用Slice、Map 先 make p1.Slice = make([]int, 5) // slice需要指定长度(容量) fmt.Println(“make后 p1 = “, p1) p1.Slice[0] = 100 p1.Map = make(map[string]string) // map会自动增长,不需要指定长度和容量 p1.Map[“hobby”] = “coding” fmt.Println(“p1 = “, p1) // { 0 0 [100 0 0 0 0] map[hobby:coding]}

// 不同结构体变量的字段互不影响 var monster1 Monster monster1.Name = “小牛” monster1.Age = 2 monster2 := monster1 // 值拷贝,互不影响 monster2.Name = “小马” fmt.Println(“monster1 = “, monster1) // {小牛 2} fmt.Println(“monster2 = “, monster2) // {小马 2} }

  1. <a name="pdHGW"></a>
  2. ## 结构体变量内存
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2932776/1637582464340-9b1efae7-2294-4dc2-a8a8-158e6a9bde84.png#clientId=ub26924f9-cccc-4&from=paste&id=u0a2aafbb&originHeight=300&originWidth=1126&originalType=binary&ratio=1&rotation=0&showTitle=false&size=194870&status=done&style=shadow&taskId=uddb10aac-c85f-4bb6-a761-2a0b4280e6c&title=)
  4. <a name="DNGwh"></a>
  5. # 结构体变量4种定义方式
  6. - new 用来分配内存,主要用来**分配值类型**,比如 int, float32, struct... **返回的是指针**。
  7. - make 用来分配内存,主要用来分配**引用类型**,比如 chan, map, slice
  8. 结构体指针
  9. ```bash
  10. package main
  11. import "fmt"
  12. type Person struct {
  13. Name string
  14. Age int
  15. }
  16. func main() {
  17. // 结构体变量定义方式
  18. // 方式1
  19. var p1 Person
  20. fmt.Println("p1 = ", p1)
  21. // 方式2
  22. // var p2 = Person{}
  23. // var p2 = Person{"tom", 10} // 这种方式要严格按照定义字段的顺序,否则类型推导报错
  24. var p2 = Person{
  25. Name: "tom",
  26. Age: 20,
  27. }
  28. fmt.Println("p2 = ", p2)
  29. // 方式3
  30. var p3 *Person = new(Person)
  31. // 指针结构体变量,标准赋值方式
  32. (*p3).Name = "abc" // 这个写法不方便
  33. // (*p3).Name = "abc" 等价于 p3.Name = "abc"
  34. // go 底层会做指针取值处理
  35. p3.Age = 3
  36. fmt.Println("p3 = ", *p3)
  37. // 方式4
  38. var p4 *Person = &Person{}
  39. (*p4).Name = "hhh"
  40. p4.Age = 5
  41. fmt.Println("p4 = ", p4)
  42. }