Go基础--Struct

结构体Struct

结构体是将零个或多个任意类型的命名变量组合在一起的聚合数据类型,每个变量都是结构体的成员

1
2
3
4
5
type Employee struct {
ID int
Name string
// ...
}

一、结构体的基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

type Employee struct {
ID int
// 相同类型的可以写在同一行
Name, Address string
Salary int
// 如果是小写开头的,该成员不可导出
test int
}
//==============
// 初始化结构体实例
//==============
var bob Employee
fmt.Println(bob) // {0 0 0}

// 结构体指针,默认为nil
var claire *Employee
fmt.Println(claire) // nil

var bobPointer *Employee = &bob
bobPointer.ID = 100
fmt.Println(bobPointer.ID) // 100
fmt.Println(bob.ID) // 100

// 初始化一个结构体类型的变量,并获得其地址
bb := &Employee{101, "name", "address", 0, 0}
fmt.Println(bb) // &{101 name address 0 0}

// 给结构体初始化赋值要么就是像bb那样,按顺序赋值,要么就是显示地指定
// 一般结构体成员少的时候,可以用第一种,通常情况下用第二种,比较明确
cc := &Employee{ID:102, Name:"name", Address:"address", Salary:0, test:0}
fmt.Println(cc)

//==============
// 结构体操作
//==============
// 通过 实例.成员变量的方式赋值或者取值
bob.ID = 103
fmt.Println(bob.ID) // 101
// 获取成员变量的地址,然后通过指针来访问
salary := &bob.Salary
*salary = 1000 + *salary
fmt.Println(bob.Salary) // 1000

结构体可以作为参数传递给函数,一般传指针,这样开销比较小

二、结构体比较

  • 如果结构体内的成员都是可比较的,那么结构体也是可比较的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type Point struct{
    X, Y int
    }

    p1 := &Point{1, 2}
    p2 := &Point{1, 2}
    p3 := &Point{2, 1}

    fmt.Println(*p1 == *p2) // true
    fmt.Println(*p1 == *p3) // false
  • 可比较的结构体,可以作为map的key类型

三、匿名成员

结构体可以进行嵌套

1
2
3
4
5
6
7
8
9
10
11
type A struct {
X int
}

type B struct {
a A
}

b := &B{}

fmt.Println(b.a.X) // 0

如果嵌套的时候,成员没有命名,那么就称为匿名成员。这时候就可以直接获取匿名成员中的成员

1
2
3
4
5
6
7
8
9
10
11
12
13
type C struct {
A
}

c := &C{}
fmt.Println(c.X) // 0

type D struct{
C
}
d := &D{}
fmt.Println(d.X) // 0

匿名成员可以是一个结构体,也可以是任何命名类型或者指向命名类型的指针

这样就可以以快捷的方式访问匿名成员内部的变量或者方法

这个机制就是从简单的类型对象组合称为复合类型的主要方式,在Go中,组合是面向对象编程的核心