結構體
結構體(struct)是用戶自定義的類型,代表若干字段的集合。有時將多個數據看做一個整體要比單獨使用這些數據更有意義,在這種情況下就適合使用結構體。
比如將一個員工的 firstName, lastName 和 age 打包在一起成為一個結構體就是很有意義的。
具名結構體
type Employee struct {
firstName, lastName string
age int
}
上面的 Employee 是一個具名結構體(named structure),因為它創建了一個具有名字的結構體類型: Employee 。
匿名結構體
我們也可以定義一個沒有類型名稱的結構體,這種結構體叫做匿名結構體(anonymous structures)。
var employee struct {
firstName, lastName string
age int
}
上面的代碼片段聲明了一個匿名結構體變量 employee。
package main
import (
"fmt"
)
func main() {
var emp1 struct {
firstName, lastName string
age int
}
emp1.firstName = "Andreah"
emp1.lastName = "Nikola"
emp1.age = 31
emp2 := struct {
firstName, lastName string
age int
}{
firstName: "Andreah",
lastName: "Nikola",
age: 31,
}
fmt.Println("Employee 1", emp1)
fmt.Println("Employee 2", emp2)
}
匿名字段
定義結構體類型時可以僅指定字段類型而不指定字段名字。這種字段叫做匿名字段(anonymous field)。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
p := Person{"Naveen", 50}
fmt.Println(p)
}
在上面的程序中,Person 是一個具有兩個匿名字段的結構體類型,類型分別為 string
和 int
。
雖然匿名字段沒有名字,但是匿名字段的默認名字為類型名。比如上面的 Person 類型,盡管它的字段是匿名的,但是默認它們擁有它們的類型的名字。因此 Person 結構體有兩個名為 string 和 int 的字段。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
var p1 Person
p1.string = "naveen"
p1.int = 50
fmt.Println(p1)
}
在上面的程序中,我們通過使用匿名字段的類型名("string"
和 "int"
)來訪問 Person 結構體的字段。
導出結構體和字段
如果一個結構體類型的名稱以大寫字母開頭,則該結構體被導出,其他包可以訪問它。同樣地,如果結構體中的字段名以大寫字母開頭,則這些字段也可以被其他包訪問。
type Spec struct { //exported struct
Maker string //exported field
model string //unexported field
Price int //exported field
}
比較結構體
結構體是值類型,如果其字段是可比較的,則該結構體就是可以比較的。如果兩個結構體變量的所有非空字段都相等,則認為這兩個結構體變量相等。
package main
import (
"fmt"
)
type name struct {
firstName string
lastName string
}
func main() {
name1 := name{"Steve", "Jobs"}
name2 := name{"Steve", "Jobs"}
if name1 == name2 {
fmt.Println("name1 and name2 are equal")
} else {
fmt.Println("name1 and name2 are not equal")
}
name3 := name{firstName: "Steve", lastName: "Jobs"}
name4 := name{}
name4.firstName = "Steve"
if name3 == name4 {
fmt.Println("name3 and name4 are equal")
} else {
fmt.Println("name3 and name4 are not equal")
}
}
在上面的程序中,name 結構體類型包含兩個 string 字段。因為 string 是可比較的,因此兩個 name 類型的變量也是可以比較的。所以,name1 和 name2 是相等的,而 name3 和 name4 是不相等的。
如果結構體包含不可比較的類型的字段,那么這兩個結構體是不可比較的。
package main
import (
"fmt"
)
type image struct {
data map[int]int
}
func main() {
image1 := image{data: map[int]int{
0: 155,
}}
image2 := image{data: map[int]int{
0: 155,
}}
if image1 == image2 {
fmt.Println("image1 and image2 are equal")
}
}
在上面的程序中,image 結構體類型包含了一個字段 data,該字段是 map 類型。map 是不可比較的類型,因此 image1 和 image2 是不可比較的。