Go语言Struct结构体-面向对象编程

1. 结构体基本介绍

Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型。Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性。

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:

Title :标题

Author : 作者

Subject:学科

ID:书籍ID

结构体成员是由一系列的成员变量构成,这些成员变量也被称为“字段”。字段有以下特性:

1、字段拥有自己的类型和值。

2、字段名必须唯一。

3、字段的类型也可以是结构体,甚至是字段所在结构体的类型。

关于 Go 语言的类(class):

Golang 没有类(class),Go 语言的结构体(struct)和其它编程语言的类(class)有同等的地位,你可以理解Golang 是基于 struct 来实现OOP(向对象编程)特性的。

备注:结构体和结构体变量(实例)的区别和联系:

1)结构体是自定义的数据类型,代表一类事物.

2)结构体变量(实例)是具体的,实际的,代表一个具体变量

2. 实例

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
package main

import "fmt"

// 定义一个Cat结构体,将Cat的各个字段/属性信息,放到Cat结构体进行管理
type Cat struct { //定义一个Cat结构体
Name string //名字
Age int //年龄
Color string //颜色
Habby string //爱好
}

func main() {
//创建一个Cat变量
var cat1 Cat //定义一个结构体变量
cat1.Name = "小白"
cat1.Age = 8
cat1.Color = "白色"
cat1.Habby = "跑步"
fmt.Println("cat1=", cat1)
fmt.Println("信息如下:")
fmt.Println("name=", cat1.Name)
fmt.Println("age=", cat1.Age)
fmt.Println("coler=", cat1.Color)
fmt.Println("habby=", cat1.Habby)
}

/*
cat1= {小白 8 白色 跑步}
信息如下:
name= 小白
age= 8
coler= 白色
habby= 跑步
*/

3. 结构体定义方式

基本结构

1
2
3
4
5
6
7
8
9
10
11
type 结构体名称 struct {  //struct是关键字,表示结构体
field1 type
field2 type
}


type Student struct {
Name string //字段
Age int //字段
Score float32
}
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
44
45
46
47
48
49
50
51
52
package main

import "fmt"

// 如果结构体的字段类型是:指针,slice,map的默认值都是nil,即还没有分配空间
// 如果需要使用这样的字段,需要先make,才能使用
type Person struct {
Name string
Age int
Scores [5]float64 //长度为 5 的浮点数组,用来存储人的五个分数
ptr *int //指针
slice []int //切片
map1 map[string]string //map
}

type Gods struct {
Name string
Age int
}

func main() {
//定义结构体变量
var p1 Person
fmt.Println(p1)
if p1.ptr == nil {
fmt.Println("ok1")
}
if p1.slice == nil {
fmt.Println("ok2")
}
if p1.map1 == nil {
fmt.Println("ok3")
}
p1.Name = "小刚"
p1.Age = 10
fmt.Println("p1=", p1)

//不同结构体变量的字段是独立,互不影响的,一个结构体变量字段的更改不影响另外一个,结构体是值类型
var god1 Gods
god1.Name = "孙悟空"
god1.Age = 1500
fmt.Println("god1=", god1)
}

/*
{ 0 [0 0 0 0 0] <nil> [] map[]}
ok1
ok2
ok3
p1= {小刚 10 [0 0 0 0 0] <nil> [] map[]}
god1= {孙悟空 1500}
*/

3.1 结构体声明变量的几种方式

备注:

  1. 第3种和第4种方式返回的是结构体指针。

  2. 结构体指针访问字段的标准方式应该是:(*结构体指针).字段名 ,比如 (*person).Name = “jack”,但 go 做了一个简化,也支持结构体指针.字段名, 比如 person.Name = “jack”。更加符合程序员使用的习惯,go 编译器底层 对 person.Name 做了转化 (*person).Name。

第一种方式 直接声明

1
var person Preson 

第二种方式 {}

1
var person Person = Person{}

第三种方式 new

1
var person *Person = new (Person)

第四种方式

1
var person *Person = &Person{}
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
44
package main

import "fmt"

type Person struct {
Name string
Age int
}

func main() {

//方式一
var p1 Person
p1.Name = "jack"
p1.Age = 18
fmt.Println(p1)

//方式二
p2 := Person{"rose", 20}
fmt.Println(p2)

//方式三
//案例 var person *Person = new (Person)
var p3 *Person = new(Person) //使用 new 函数分配内存
(*p3).Name = "tom" //等价于p3.Name="tom"
//因为p3是一个指针,因此标准的给字段赋值的方式
//(*p3).Name = "tom"也可以写为p3.Name="tom"
//原因:go的设计者为了程序员使用方便,底层会对p3.Name ="tom"处理
//会给p3加上取值运算(*p3).Name="Tom"
(*p3).Age = 90 //等价于p3.Age = 100
fmt.Println(*p3)

//方式四
//案例:var person *Person=&Person{}
var person *Person = &Person{Name: "Bob", Age: 25}
fmt.Println(*person)
}

/*
{jack 18}
{rose 20}
{tom 90}
{Bob 25}
*/

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!