原文
結構是一個包含很多字段名字和類型的集合闸翅。通常它是這樣的:
package main
import "fmt"
type Person struct {
name string
age int32
}
func main() {
person := Person{name: "Micha?", age: 29}
fmt.Println(person) // {Micha? 29}
}
(在本文章的其余部分,包名辜伟,導入氓侧,和主函數(shù)都會省略掉脊另,不寫咯)
上面的結構的每一個字段都有各自的名字导狡。Go也允許跳過字段名字。字段沒有名字叫做匿名或者嵌入偎痛。類型的名字(沒有當前包的前綴)會被當作字段的名字旱捧。由于結構的字段名稱必須唯一,所以我們不能這樣做:
import (
"net/http"
)
type Request struct{}
type T struct {
http.Request // field name is "Request"
Request // field name is "Request"
}
這樣編譯器會拋出錯誤:
> go install github.com/mlowicki/sandbox
# github.com/mlowicki/sandbox
src/github.com/mlowicki/sandbox/sandbox.go:34: duplicate field Request
結構內(nèi)匿名字段的方法和字段可以很簡單的訪問到:
type Person struct {
name string
age int32
}
func (p Person) IsAdult() bool {
return p.age >= 18
}
type Employee struct {
position string
}
func (e Employee) IsManager() bool {
return e.position == "manager"
}
type Record struct {
Person
Employee
}
...
record := Record{}
record.name = "Micha?"
record.age = 29
record.position = "software engineer"
fmt.Println(record) // {{Micha? 29} {software engineer}}
fmt.Println(record.name) // Micha?
fmt.Println(record.age) // 29
fmt.Println(record.position) // software engineer
fmt.Println(record.IsAdult()) // true
fmt.Println(record.IsManager()) // false
匿名(嵌入)字段的方法和字段叫做提升。它們看上去像普通字段枚赡,但是它們不能通過結構初始化:
//record := Record{}
record := Record{name: "Micha?", age: 29}
編譯器會拋出錯誤:
> go install github.com/mlowicki/sandbox
# github.com/mlowicki/sandbox
src/github.com/mlowicki/sandbox/sandbox.go:34: duplicate field Request
如果要聲明的話氓癌,就必須創(chuàng)建整個匿名(嵌入)字段結構:
Record{Person{name: "Micha?", age: 29}, Employee{position: "Software Engineer"}}