提升Go的字段和方法

原文

结构是一个包含很多字段名字和类型的集合。通常它是这样的:

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"}}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容