1、定義
Go語言可以通過自定義的方式形成新的類型,結構體就是這些類型中的一種復合類型,結構體是由零個或多個任意類型的值聚合成的實體,每個值都可以稱為結構體的成員。
結構體成員也可以稱為“字段”,這些字段有以下特性:
- 字段擁有自己的類型和值;
- 字段名必須唯一;
- 字段的類型也可以是結構體,甚至是字段所在結構體的類型。
結構體的定義格式如下:
type 類型名 struct {
字段1 字段1類型
字段2 字段2類型
…
}
對各個部分的說明:
- 類型名:標識自定義結構體的名稱,在同一個包內不能重復。
- struct{}:表示結構體類型,
type 類型名 struct{}
可以理解為將 struct{} 結構體定義為類型名的類型。 - 字段1、字段2……:表示結構體字段名,結構體中的字段名必須唯一。
- 字段1類型、字段2類型……:表示結構體各個字段的類型。
2、實例化
Go語言可以通過多種方式實例化結構體,根據實際需要可以選用不同的寫法。
1)基本實例化格式
var ins T
其中,T 為結構體類型,ins 為結構體的實例。
使用.
來訪問結構體的成員變量。
示例:
package main import "fmt" func main() { type Point struct { X int Y int } var p Point p.X = 10 p.Y = 20 fmt.Printf("x = %d, y = %d\n", p.X, p.Y) }
2)創建指針類型的結構體
Go語言中,還可以使用 new 關鍵字對類型(包括結構體、整型、浮點數、字符串等)進行實例化,結構體在實例化后會形成指針類型的結構體。
使用 new 的格式如下:
ins := new(T)
其中:
- T 為類型,可以是結構體、整型、字符串等。
- ins:T 類型被實例化后保存到 ins 變量中,ins 的類型為 *T,屬於指針。
在Go語言中,訪問結構體指針的成員變量時可以繼續使用.,這是因為Go語言為了方便開發者訪問結構體指針的成員變量,使用了語法糖技術,將 ins.Name 形式轉換為 (*ins).Name。
示例:
package main import "fmt" func main() { type Point struct { X int Y int } p := new(Point) p.X = 10 p.Y = 20 fmt.Printf("x = %d, y = %d\n", p.X, p.Y) }
3)取結構體的地址實例化
在Go語言中,對結構體進行&
取地址操作時,視為對該類型進行一次 new 的實例化操作,取地址格式如下:
ins := &T{}
其中:
- T 表示結構體類型。
- ins 為結構體的實例,類型為 *T,是指針類型。
示例:
package main import "fmt" func main() { type Point struct { X int Y int } p := &Point{ 1, 2, } fmt.Printf("x = %d, y = %d\n", p.X, p.Y) }
3、初始化
結構體在實例化時可以直接對成員變量進行初始化,初始化有兩種形式分別是以字段“鍵值對”形式和多個值的列表形式,鍵值對形式的初始化適合選擇性填充字段較多的結構體,多個值的列表形式適合填充字段較少的結構體。
1)使用鍵值對初始化
結構體可以使用“鍵值對”初始化字段,每個“鍵”對應結構體中的一個字段,鍵的“值”對應字段需要初始化的值。
鍵值對的填充是可選的,不需要初始化的字段可以不填入初始化列表中。
結構體實例化后字段的默認值是字段類型的默認值,例如 ,數值為 0、字符串為 ""(空字符串)、布爾為 false、指針為 nil 等。
鍵值對初始化的格式如下:
ins := 結構體類型名{
字段1: 字段1的值,
字段2: 字段2的值,
…
}
說明:
- 結構體類型:定義結構體時的類型名稱。
- 字段1、字段2:結構體成員的字段名,結構體類型名的字段初始化列表中,字段名只能出現一次。
- 字段1的值、字段2的值:結構體成員字段的初始值。
注意:結構體成員中只能包含結構體的指針類型,包含非指針類型會引起編譯錯誤。
示例:
package main import "fmt" func main() { type People struct { name string child *People } relation := &People{ name: "爺爺", child: &People{ name: "爸爸", child: &People{ name: "我", }, }, } fmt.Println(relation.name) fmt.Println(relation.child.name) fmt.Println(relation.child.child.name) }
2)使用多個值的列表初始化結構體
Go語言可以在“鍵值對”初始化的基礎上忽略“鍵”,也就是說,可以使用多個值的列表初始化結構體的字段。
多個值的列表初始化格式:
ins := 結構體類型名{
字段1的值,
字段2的值,
…
}
使用這種格式初始化時,需要注意:
- 必須初始化結構體的所有字段。
- 每一個初始值的填充順序必須與字段在結構體中的聲明順序一致。
- 鍵值對與值列表的初始化形式不能混用。
示例:
package main import "fmt" func main() { type Point struct { X int Y int } p := Point{ 1, 2, } fmt.Printf("x = %d, y = %d\n", p.X, p.Y) }
3)初始化匿名結構體
匿名結構體的初始化寫法由結構體定義和鍵值對初始化兩部分組成,結構體定義時沒有結構體類型名,只有字段和類型定義,鍵值對初始化部分由可選的多個鍵值對組成,如下格式所示:
ins := struct {
// 匿名結構體字段定義
字段1 字段類型1
字段2 字段類型2
…
}{
// 字段值初始化
初始化字段1: 字段1的值,
初始化字段2: 字段2的值,
…
}
說明:
- 字段1、字段2……:結構體定義的字段名。
- 初始化字段1、初始化字段2……:結構體初始化時的字段名,可選擇性地對字段初始化。
- 字段類型1、字段類型2……:結構體定義字段的類型。
- 字段1的值、字段2的值……:結構體初始化字段的初始值。
鍵值對初始化部分是可選的。
示例:
package main import "fmt" func main() { p := struct { X int Y int }{ X : 1, Y : 2, } fmt.Println(p) }