Golang 入門 結構體 struct

2022-01-12 22:27:52 字數 4137 閱讀 8677

go 通過型別別名(alias types)和結構體的形式支援使用者自定義型別,或者叫定製型別。試圖表示乙個現實世界中的實體。

結構體由一系列命名的元素組成,這些元素又被稱為字段,每個欄位都有乙個名稱和乙個型別。

結構體的目的就是把資料聚集在一起,以便能夠更加便捷地操作這些資料。結構體的概念在 c 語言裡很常見,被稱為 struct。golang 中的結構體也是 struct。go 語言中沒有類的概念,因此在 go 中結構體有著更為重要的地位。結構體是復合型別(composite types),當需要定義乙個型別,它由一系列屬性組成,每個屬性都有自己的型別和值的時候,就應該使用結構體,它把資料聚集在一起。然後可以訪問這些資料,就好像它是乙個獨立實體的一部分。結構體也是值型別,因此可以通過 new 函式來建立。

在 golang 中最常用的方法是使用關鍵字 type 和 struct 來定義乙個結構體,以關鍵字 type 開始,之後是新型別的名字,最後是關鍵字 struct:

//

person 為使用者定義的乙個型別

type person struct

還有一些簡單的寫法,比如:

type t struct

也是合法的,它更適用於簡單的結構體。

結構體裡的字段都有名字,比如上面例子中的 name、age 和 email 等等。如果乙個欄位在**中從來不會被用到,那可以把它命名為 _,即空識別符號。

結構體中的字段可以是任何型別,甚至是結構體本身,也可以是函式或者介面。可以宣告結構體型別的乙個變數,然後像下面這樣給它的字段賦值:

var p person

p.name = "

nick

"p.age = 28

另外,陣列可以看作是一種結構體型別,不過它使用下標而不是具名的字段。

字段標記

在定義結構體時還可以為字段指定乙個標記資訊:

type person struct

這些標記資訊通過反射介面可見,並參與結構體的型別標識,但在其他情況下被忽略。

一旦定義了結構體型別就可以使用這個型別建立值。

使用結構型別宣告變數,並初始化為零值

var nick person

關鍵字 var 建立了型別為 person 且名為 nick 的變數。nick 被稱作型別 person 的乙個例項(instance)或物件(object)。注意:當宣告變數時,這個變數對應的值總是會被初始化。這個值要麼用指定的值初始化,要麼用零值(即變數型別的預設值)做初始化。對數值型別來說,零值是 0;對字串來說,零值是空字串;對布林型別,零值是 false。

通過上面的方式宣告結構體型別的變數,結構體裡的每個欄位都會用零值初始化。任何時候,建立乙個變數並初始化為零值,習慣上會使用關鍵字 var。這種用法是為了更明確地表示乙個變數被設定為零值。

使用結構體字面量宣告變數,並初始化為非零值

如果希望變數被初始化為某個非零值,可以通過結構體字面量和短變數宣告操作符(:=)來建立變數。下面的**展示了如何宣告乙個 persion 型別的變數,並使用某個非零值作為初始值。

//

宣告 person 型別的變數,並初始化所有字段

nick :=person

在第一行中我們給出了乙個變數名 nick,之後是短變數宣告操作符。這個操作符是冒號加乙個等號 (:=)。乙個短變數宣告操作符在一次操作中完成兩件事情:宣告乙個變數,並初始化。短變數宣告操作符會使用右側給出的型別資訊作為宣告變數的型別。

短變數宣告操作符(:=)

它的作用是宣告並且賦值乙個變數,其好處是不需要寫 var 三個字母,另外不需要寫型別,golang 語言會自動根據賦值的內容確定型別。

使用短變數宣告操作符也有一些限制,比如不能在函式外面使用,即不能用來宣告全域性變數。另外短變數宣告操作符左邊至少得有乙個變數是沒有定義過的。

字面量的兩種寫法

結構體字面量可以對結構體型別進行初始化,比如前面介紹過的示例:

nick :=person

這種形式在不同行宣告每個欄位的名字以及對應的值。欄位名與值用冒號分隔,每一行以逗號結尾。這種形式對字段的宣告順序沒有要求。

第二種形式沒有欄位名,只宣告對應的值,如下面的**:

nick := person

每個值也可以分別佔一行,不過習慣上這種形式會寫在一行裡,結尾不需要逗號。這種形式

下,值的順序很重要,必須要和結構宣告中字段的順序一致。

new 是乙個用來分配記憶體的內建函式,但是與 c++ 不一樣的是,它並不初始化記憶體,只是將其置零。也就是說,new(t) 會為型別 t 分配被置零的記憶體,並且返回它的位址,乙個型別為 *t 的值。在 golang 的術語中,其返回乙個指向新分配的型別為 t 的指標,這個指標指向的內容的值為零(zero value)。比如下面的**:

nick := new(person)

這裡的變數 nick 是乙個指標:

fmt.printf("

%t", nick)

輸出的結果為:*main.student

而通過下面方式宣告的變數:

var nick person

型別則是:main.student

使用 new 函式時,宣告變數和分配記憶體並不需要放在一起,可以先宣告乙個變數,然後再通過 new 函式為之分配記憶體,比如下面的寫法:

var nick *person

nick = new (person)

new 函式的特點是只能把記憶體初始化為零值並返回其指標,如果要通過字面量初始化該記憶體就需要使用混合字面量語法(composite literal syntax)

&t

比如下面的寫法:

nick := &person

此時 nick 的型別也是 *person。因此我們可以得出下面的結論:

表示式 new(type) 和 &type{} 是等價的。

在 golang 中,訪問結構體成員需要使用點號操作符,點號操作符也被稱為選擇器(selector),使用時的格式為:

結構體.成員名

注意:這裡的 "結構體" 是指結構體型別的變數或結構體指標型別的變數。無論變數是乙個結構體型別還是乙個結構體型別指標,都可以使用相同的選擇器服務來引用結構體的字段。

結構體可以包含乙個或多個匿名(或者稱為內嵌)字段,即這些字段沒有顯式的名字。僅指明欄位的型別,此時該型別就是欄位的名字。匿名字段本身可以是乙個結構體型別,即結構體可以包含內嵌的結構體。

匿名字段

匿名欄位和物件導向程式設計中的繼承概念相似,可以被用來模擬類似繼承的行為。golang 中的基礎就是通過內嵌或組合來實現的,所以說在 golang 中組合比繼承更受歡迎。比如下面的例子:

type test struct

內嵌結構體

結構體也是一種資料型別,所以它同樣可以作為匿名字段使用:

type person struct 

type student struct

下面的**可以宣告並初始化 student 型別的變數:

st :=student ,

studentid:

1000

,}

從這個示例可以看出,內層結構體被簡單地插入或者內嵌進外層結構體。這種簡單的 "繼承" 機制使得 golang 很輕鬆就能實現從乙個或一些型別中繼承部分或全部的實現。

golang 中沒有類的概念,因此在 golang 中結構體有著更為重要的地位。所以學習並掌握結構體是入門 golang 的關鍵步驟。希望本文能夠幫助大家理解 golang 結構體的基本概念和用法。

參考:

golang struct types

《go語言程式設計入門與實戰技巧》

結構體定義

go 語言的變數宣告並賦值運算子(:=)

Golang結構體知識

在看docker原始碼時,碰到了這個語句 container.lock 看到上面直接對struct container進行上鎖時,我翻了一下這個結構體,發現沒有定義任何鎖啊,怎麼上鎖的咧。於是我就翻了一下這個結構 體的一些子屬性,發現了state的定義 container container.go ...

Golang 學習 結構體

結構體定義 結構體是一種資料型別。定義型別 地位等價於 int byte bool string.通常放在全域性位置 type person struct 注意 結構體內不能賦初值,不能用 var 修飾。普通變數定義和初始化 普通變數的賦值和使用 使用 索引成員變數。var man person m...

Golang結構體初探

go語言中的基礎資料型別可以表示一些事物的基本屬性,但是當我們想表達乙個事物的全部或部分屬性時,這時候再用單一的基本資料型別明顯就無法滿足需求了,go語言提供了一種自定義資料型別,可以封裝多個基本資料型別,這種資料型別叫結構體,英文名稱struct。也就是我們可以通過struct來定義自己的型別了。...