原文
结构是一个包含很多字段名字和类型的集合。通常它是这样的:
package main
import "fmt"
type Person struct {
name string
age int32
}
func main() {
person := Person{name: "Michał", age: 29}
fmt.Println(person) // {Michał 29}
}
(在本文章的其余部分,包名,导入,和主函数都会省略掉,不写咯)
上面的结构的每一个字段都有各自的名字。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
结构内匿名字段的方法和字段可以很简单的访问到:
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
如果要声明的话,就必须创建整个匿名(嵌入)字段结构:
Record{Person{name: "Michał", age: 29}, Employee{position: "Software Engineer"}}