Friday, January 14, 2022

[用Golang寫小遊戲教學] 第六章 結構 (Struct)

 

[前言]

我們在有些情況會希望把一些資料(有相關性)集結在一個結構內,舉例來說,一張身分證內包含了: 姓名、身份證字號、戶籍地、出生日期、配偶等等的資料,如果我們可以用一種型別可以包含上述這些資料,對於管理資料來說就會方便許多。如果大家有學過C語言的話,就會知道struct 這個複合資料型別。在Golang,就是把在C語言內的struct搬過來使用,並稱之為結構 (Struct)型別。而且,還可以賦予它擁有函數的做法,稱之為Receiver。

注意: 我們暫時不提interface,因為會太複雜ㄡ!


[定義結構(Struct)]

在Golang的定義結構 (Struct) 是使用 type 關鍵字基於 struct 來定義一個新的型別,語法用下列例子說明:

type IdentityCard struct {
myID string
myAge int
}

上述我們定義了一個新的struct型別,名稱是IdentityCard,裡面包含了兩個變數:myID與myAge。但,只是定義新的struct型別還不夠,我們需要宣告變數與初始化它才能使用。關於變數宣告可參考之前的文章: 
[用Golang寫小遊戲教學] 第二章 基本型別、變數宣告與常數宣告 

myIdCard = IdentityCard{"myID: "Danny", myAge: 18} 
myIdCard.myID 可以得到 "Danny"
myIdCard.myAge 可以得到 18

初始化的時候可以直接先給值或是之後再給都可以。當我們要拿myIdCard 內的值時,要在後面加句點".",如果我們給個初始值:

請看下列範例:
var myIdCard IdentityCard
myIdCard = IdentityCard{"myID: "Danny", myAge: 18}

//或是使用懶人法 myIdCard := IdentityCard{myID: "Danny", myAge: 18}

//之後再修改值
myIdCard.myAge = 20

fmt.Println("Hello,", myIdCard.myID, myIdCard.myAge)

完整例子請參考下列

結果:
Hello, Danny 20

注意: 如果使用new這關鍵字去初始化我們struct型別的變數會是以指標方式儲存在變數內,這部分關於指標內容先跳過~


[結構(Struct) Receiver]

我們在前言有提到,Golang提供了綁定函式到特定型別(type)成為其所擁有的一個函式,此結構(Struct)型態被稱之為Receiver。綁定函式到特定結構(Struct)型別是十分常見的用法,一定要會。

上面的描述的可能很難一目了然,請看以下面例子(改寫上述的例子,結果相同)

type IdentityCard struct {
myID string
myAge int
}

func (idc IdentityCard) getData() string {
return fmt.Sprint(idc.myID, " ", idc.myAge)
}

我們把getData()函式綁定給 type IdentityCard struct,所以(idc IdentityCard) 內的參數idc即為Receiver,透過idc可以取得此結構型別內的資料或是呼叫其他綁定的函式。在上述的例子中,getData() 取得 idc (Receiver) 內的 idc.myID 與 idc.myAge,並透過 fmt.Sprint() 回傳整理格式後的字串。


完整例子請參考下列

結果:
Hello, Danny 20

No comments: