Hike News
Hike News

Golang物件導向初識-day13-結構體(struct)

introduction

  1. 用來自定義複雜的數據結構,亦為一種自定義的類型(與golang自帶的int,string,map類型等價)
  2. struct可以包含多個字段,或稱屬性
  3. struct類型可以定義方法,須注意和函數的區分
  4. struct類型屬於值類型,因此要修改struct中的值,必須傳入指針
  5. struct之間可以嵌套,自定義的struct中可再包含其他struct類型
  6. Golang中沒有class類型,只有struct類型
    • 可將struct類型當作class類型使用

定義struct

type定義一個自定義的類型,也包括自定義struct

1
2
3
4
5
type structstruct {
字段1 類型
字段2 類型
字段3 類型
}

  • 結構體中可包含多個字段

example

1
2
3
4
5
type Student struct {
Name string
Age int
Score float64
}

初始化

初始化為空

1
2
3
4
5
6
7
8
9
10
11
12
13
type Student struct {
Name string
Age int
Score float64
}

func main(){

//聲明一個Student類型(struct)的變量
var A Student

var AA Student = Student{}
}
  • 當其初始化時字段皆為空

初始化時賦值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Student struct {
Name string
Age int
Score float64
}


func main(){
var B Student = Student{
Name : "Jack", //[1]
Age : 20,
Score: 89.5, //[1]
}
}

[1] 字段之間賦值需用,隔開,最後字段也需以,結尾

tips

  • 亦可初始化部分字段,未初始化的字段會為空

使用new初始化(返回指針)

struct為值類型,也可使用new函數初始化

  • 注意!返回的為指針類型
1
2
3
4
5
6
7
8
9
10
11
type Student struct {
Name string
Age int
Score float64
}

func main(){
var C *Student = new(Student) //[1]

D := new(Student)
}

[1] *Student為Student類型的指針


取址符& 初始化(返回指針)

1
2
3
4
5
6
7
8
9
type Student struct {
Name string
Age int
Score float64
}

func main(){
var E *Student = &Student{} //[1]
}

[1] E變量的值是使用&取址;所以類型應為*Student,接收Student類型的指針


字段訪問

上數有提到struct類型可當作class類型來使用
所以要訪問struct中的字段(屬性),與其他語言一樣,使用struct名.字段訪問及賦值

  • 字段名為大寫是外部包可訪問的
  • 字段名小寫表示為私有字段,外部不可訪問
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
package main

import (
"fmt"
)

type Student struct {
Name string
Age int
Score float64
}

func print_info(name string,age int,score float64){
fmt.Printf("%s's age is %d, he got %.1f point\n",name,age,score)
}

func main(){
var A Student

//使用 struct名.字段 賦值
A.Name = "Tom"
A.Age = 18
A.Score = 90.0

var B Student = Student{
Name : "Jack",
Age : 20,
Score: 89.5,
}

//使用 struct名.字段 訪問
print_info(A.Name,A.Age,A.Score)
print_info(B.Name,B.Age,B.Score)
}

result

1
2
Tom's age is 18, he got 90.0 point
Jack's age is 20, he got 89.5 point

訪問指針類型的struct 字段

照理來說訪問指針類型的struct 字段應為

1
(*變量).字段

但Golang做了簡化,會自動判斷是否為指針類型自動轉換
所以即使使用

1
變量.字段

仍能訪問

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
)

type Student struct {
Name string
Age int
Score float64
}

func main(){
var E *Student = &Student{}

(*E).Name = "Curtis"
E.Age = 18
E.Score = 100.0

fmt.Println(*E)
}

result

1
{Curtis 18 100}

struct的內存布局

struct中所有的字段在內存都是連續的(與陣列相同),布局如下
struct

從圖中可以看到,即使結構體接收的為指針類型
兩指針的存放的地址是連續的
只是兩指針是指向不同的內存地址,指向的內存地址不連續而已

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
"fmt"
)

type Student struct {
Name string
Age int
Score float64
}

func main(){
var E *Student = &Student{
Name : "Curtis",
Age : 20,
Score : 80.0,
}

fmt.Printf("Name:%p\n",&E.Name)
fmt.Printf("Age: %p\n",&E.Age)
fmt.Printf("Score:%p\n",&E.Score)
}

result

1
2
3
Name:0xc04205a3e0
Age: 0xc04205a3f0
Score:0xc04205a3f8