首页 > 其他分享 >go 组合取代继承

go 组合取代继承

时间:2022-11-15 12:01:21浏览次数:47  
标签:取代 string author 继承 fmt Println go Go post

Go 不支持继承,但它支持组合(Composition)。组合一般定义为“合并在一起”。汽车就是一个关于组合的例子:一辆汽车由车轮、引擎和其他各种部件组合在一起。

通过嵌套结构体进行组合

在 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)
}
复制代码

在上面的代码片段中,我们创建了一个 author 结构体, author 的字段有 firstnamelastname 和 bio。我们还添加了一个 fullName() 方法,其中 author 作为接收者类型,该方法返回了作者的全名。

下一步我们创建 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。该字段指定 author  组成了 post  结构体。现在 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()
}
复制代码

在 playground 上运行

在上面程序中,main 函数在第 31 行新建了一个 author 结构体变量。而在第 36 行,我们通过嵌套 author1 来创建一个 post。该程序输出:

Title:  Inheritance in Go  
Content:  Go supports composition instead of inheritance  
Author:  Naveen Ramanathan  
Bio:  Golang Enthusiast

结构体切片的嵌套

我们可以进一步处理这个示例,使用博客帖子的切片来创建一个网站。
我们首先定义 website 结构体。请在上述代码里的 main 函数中,添加下面的代码,并运行它。

复制代码
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 添加了字段名 posts

现在我们来修改主函数,为我们的新网站创建一些帖子吧。

修改后的完整代码如下所示:

复制代码
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()
}
复制代码

在 playground 中运行

在上面的主函数中,我们创建了一个作者 author1,以及三个帖子 post1post2和 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

标签:取代,string,author,继承,fmt,Println,go,Go,post
From: https://www.cnblogs.com/cheyunhua/p/16891963.html

相关文章

  • PyMongo的安装(windows环境)
    PyMongo的安装(windows环境)❤第一步:下载PyMongo下载地址:https://github.com/mongodb/mongo-python-driver/archive/refs/tags/3.13.0.zip❤第二步:安装解压安装包......
  • python django
    1、安装django2、查django版本python-mdjango--version3、创建django项目cdC:\Curtis\Python\Project4、django-adminstartprojectMySiteMySite是创建的djang......
  • google网页翻译无法使用
    复制以下脚本到本地txt文件中,更改后缀为.bat以管理员身份执行bat脚本即可@setlocalenabledelayedexpansion@echooffset"source_domain=google.cn"set"target_dom......
  • DNS大全(114DNS 、阿里DNS、百度DNS 、360 DNS、Google DNS)
    DNS是什么: DNS是域名系统,DomainNameSystem的缩写,是一个服务。 DNS就是把域名解析为IP地址,提供我们上网,我们能够上网最终是找到IP地址。比如,http://xxxx.com是域......
  • go--类型转换
    1int与string备注:string不可直接转int32,先转为int,再转成int32packagemainimport("fmt""strconv")funcmain(){//int转stringvaraint......
  • GO读取Yaml文件
    yaml语法简介YAML语言(发音/ˈjæməl/)的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。YAML有一个小的怪癖。所有的YAML文件开始行都应该是--......
  • GO读取toml格式文件
    在toml以#作为注释,文件内容也是需要有一个section其下内容以key=value书写,key不能为空,但是可以是空引号,key可以用双引号也可以不用,value是字符串时需要用双引号引......
  • GO 你知道吗【5】
    GO你知道吗函数的接收者,效果在同一个go文件中方法名相同,返回值相同,接收者不同这个接收者机制类似于隐式多态......
  • day31 1 tomcat介绍与创建web项目 & 2 继承HttpServlet类、配置webxml全局配置文件 &
    ServletJavaServlet是运行在Web服务器或应用服务器上的程序,作为客户端(Web浏览器或其他HTTP客户端)和服务端(HTTP服务器上的数据库或应用程序)之间的中间层。使用Servlet可......
  • mongodb通过非映射方式操作documnet
    前言我是MongoDB小白,刚开始学。不过,我猜大多数使用MongoDB的,都是采用映射方式处理的,即需要有定义好的用于映射的实体类。但是这样的话,如果表的结构在未来可能频繁变......