在 Go 裡,struct 是一連串具名元素組成的序列,這些元素稱為_欄位_,每個欄位都有名稱與型別。欄位名稱在同一個 struct 內必須是唯一的。struct 可以對比物件導向程式設計裡的_類別_。
你可以使用type和struct這兩個關鍵字來建立新的 struct,並明確定義每個欄位的名稱與型別。舉例來說,這裡我們定義了一個 Shape struct,用來保存形狀的名稱和大小:
type Shape struct {
name string
size int
}
struct 的欄位命名遵循 Go 的慣例:以小寫字母開頭的欄位,只有同一個套件裡的程式碼能看見;以大寫字母開頭的欄位,則在其他套件裡也能看見。
定義好struct之後,你需要建立新的實例,用欄位名稱來指定欄位的值,順序不拘:
s := Shape {
name: "Square",
size: 25,
}
要讀取或修改實例的欄位,請使用.標記法:
// Update the name and the size
s.name = "Circle"
s.size = 35
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 35
沒有指定初始值的欄位,會取得它們的零值。例如:
s := Shape{name: "Circle"}
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 0
只要_依序_定義欄位,你也可以建立struct的實例而不使用欄位名稱:
s := Shape {
"Oval",
20,
}
不過,這種寫法被視為_脆弱的程式碼_,因為一旦新增欄位就可能出錯,尤其是新欄位的型別不同時。在下面的例子裡,我們在Shape中多加了一個欄位:
type Shape struct {
name string
description string // new field 'description' added
size int
}
s := Shape{
"Circle",
20,
}
// Since the second field of the struct is now a string and not an int,
// the compiler will throw an error when compiling the program:
// Output: cannot use 20 (type untyped int) as type string in field value
// Output: too few values in Shape{...}
有時候,有些函式能幫我們建立 struct 的實例會很方便。依照慣例,這類函式通常叫做New,或名稱以New開頭,但因為它們只是一般的函式,你可以隨意替它們命名。它們或許會讓你想起其他語言裡的建構子,但在 Go 裡,它們就只是一般的函式。
在下面的例子中,其中一個New函式用來建立Shape的新實例,並自動為形狀的size設定預設值:
func NewShape(name string) Shape {
return Shape{
name: name,
size: 100, //default-value for size is 100
}
}
NewShape("Triangle")
// => Shape { name: "Triangle", size: 100 }
使用New函式有以下幾個好處:
New函式通常和它們所初始化的 struct 宣告在同一個套件裡,所以它們甚至能初始化 struct 的私有欄位想更深入了解這個型別,你可以參考這些資源:Go by Example: Structs、A Tour of Go: Structs 或 Structures in Go (structs)
new 內建函式另一種建立 struct 新實例的方式,是使用new這個內建函式:
s := new(Shape) // s will be of type *Shape (pointer to shape)
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: size: 0
在這個例子裡,new建立了 struct Shape的實例,所有值都初始化為其型別的零值,並回傳指向它的指標。
大多數情況下,你不會看到有人用new內建函式來建立 struct 的新實例。
請盡量優先使用 struct 字面值、自訂的New函式,或套件提供的其他任何能幫你建立 struct 的函式。
只有在別無選擇時,才使用new內建函式來建立 struct 的新實例。