欢迎继续Golang系列教程第27节
Go并不支持继承,但是它支持组合。组合的通用定义是 “放到一起”。组合的一个例子是 汽车,汽车由车轮,引擎和各种其他部件组成。
通过嵌入结构体组合
在 Go 中,组合可以通过将一个结构体类型嵌入另一个来获得。
博客文章是组合的一个完美例子。每个博客文章都有一个标题,内容和作者信息。这可以通过使用组合完美地表示。在文章的下一步,我们将学习这些是如何完成的。
我们首先创建 author 结构体。
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
在上面的代码片段,我们创建一个有 firstname,lastName 和 bio 字段的结构体 author。我们也使用 author 作为接收器类型添加一个方法 fullName(),该方法返回一个作者的全名字。
下一步将创建一个 post 结构体。
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.author.fullName())
fmt.Println("Bio: ", p.author.bio)
}
post 结构体有字段 title,content。它还有一个嵌入的匿名字段 author。这个字段表示 post结构体由 author组合而成。现在 post 结构体可以访问 author 结构体的所有字段和方法。我们还为 post 结构体添加 details() 方法,它将打印标题,内容和作者的命名和个人简历。
当一个结构体字段嵌入的是另一个结构体,Go 给我们提供了访问嵌入字段的选项,就好比他们是外部结构体的一部分一样。这意味着上面代码第 11 行的 p.author.fullName() 可以使用 p.fullName() 代替。因此 details() 方法可以像下面一样重写。
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
现在我们已经准备了 author 和 post 结构体。我们创建一个博客文章来完成这个程序
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
func main() {
author1 := author{
"Naveen",
"Ramanathan",
"Golang Enthusiast",
}
post1 := post{
"Inheritance in Go",
"Go supports composition instead of inheritance",
author1,
}
post1.details()
}
上面程序的主函数在第 31 行创建一个新的作者。在第 36 行通过嵌入 author1 创建一个新的博客文章 。这个程序打印
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
嵌入结构体切片
我们要以继续这个例子,使用博客文章切片 创建一个 web 站点。
我们首先定义 website 结构体。在上面已有的程序主函数添加下列代码并运行它。
type website struct {
[]post
}
func (w website) contents() {
fmt.Println("Contents of Website\n")
for _, v := range w.posts {
v.details()
fmt.Println()
}
}
当在添加完上面代码后运行程序,编译器将报如下错误:
main.go:31:9: syntax error: unexpected [, expecting field name or embedded type
这个错误指向嵌入的结构体切片 []post。原因是不能匿名嵌入一个切片。需要一个字段名。所以我们来修复该错误
type website struct {
posts []post
}
向 post 切片 []post 添加字段名 posts。
现在修改主函数,为 website 创建一个一些贴子。
修改完主函数后的完整程序提供如下
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
type website struct {
posts []post
}
func (w website) contents() {
fmt.Println("Contents of Website\n")
for _, v := range w.posts {
v.details()
fmt.Println()
}
}
func main() {
author1 := author{
"Naveen",
"Ramanathan",
"Golang Enthusiast",
}
post1 := post{
"Inheritance in Go",
"Go supports composition instead of inheritance",
author1,
}
post2 := post{
"Struct instead of Classes in Go",
"Go does not support classes but methods can be added to structs",
author1,
}
post3 := post{
"Concurrency",
"Go is a concurrent language and not a parallel one",
author1,
}
w := website{
posts: []post{post1, post2, post3},
}
w.contents()
}
在上面的主函数中,我们创建一个作者 author1 和三个贴子 post1,post2 和 post3。最后我们在第 62 行通过嵌入这三个贴子创建一个站点 w,在下一行打印内容。
程序将输出
Contents of Website
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
Title: Struct instead of Classes in Go
Content: Go does not support classes but methods can be added to structs
Author: Naveen Ramanathan
Bio: Golang Enthusiast
Title: Concurrency
Content: Go is a concurrent language and not a parallel one
Author: Naveen Ramanathan
Bio: Golang Enthusiast
**下一教程 - 多态 **
本文是Golang系列教程第27节,介绍了通过嵌入结构体组合和嵌入结构体切片的方法。通过博客文章的例子,展示了如何将一个结构体类型嵌入另一个结构体以实现组合,还说明了在使用结构体切片时遇到的问题及解决办法。
602

被折叠的 条评论
为什么被折叠?



