From 1e467cfb71b4aeb56d2681e3acb631f7095cd141 Mon Sep 17 00:00:00 2001 From: leisore Date: Tue, 11 Aug 2015 14:40:37 +0800 Subject: [PATCH] 10.6.6 OK --- eBook/10.6.md | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/eBook/10.6.md b/eBook/10.6.md index 820d89b..74bdd6d 100644 --- a/eBook/10.6.md +++ b/eBook/10.6.md @@ -416,7 +416,117 @@ func (n *NamedPoint) Abs() float64 { 然后仅在Mercedes类型上创建方法sayHiToMerkel()并调用它。 -** 10.6.6 +** 10.6.6 如何在类型中嵌入功能 + +主要有两种方法来实现在类型中嵌入功能: + +A. 聚合(或组合):包含一个所需功能类型的具名字段 +B. 内嵌:内嵌(匿名地)所需功能类型,像前一节10.6.5 所示的那样 + +为了使这些概念具体化,假设有一个Customer类型,我们想让它通过Log类型来包含日志功能,Log类型只是简单地包含一个累积的消息(当然它可以是复杂的)。如果想让特定类型都具备日志功能,你可以实现一个这样的Log类型,然后将它作为特定类型的一个字段,并提供Log(),它返回这个日志的引用。 + +方式A可以通过如下方法实现(使用了10.7中的String()功能): + +Listing 10.19—embed_func1.go: +```go +package main + +import ( + "fmt" +) + +type Log struct { + msg string +} + +type Customer struct { + Name string + log *Log +} + +func main() { + c := new(Customer) + c.Name = "Barak Obama" + c.log = new(Log) + c.log.msg = "1 - Yes we can!" + // shorter + c = &Customer{"Barak Obama", &Log{"1 - Yes we can!"}} + // fmt.Println(c) &{Barak Obama 1 - Yes we can!} + c.Log().Add("2 - After me the world will be a better place!") + //fmt.Println(c.log) + fmt.Println(c.Log()) + +} + +func (l *Log) Add(s string) { + l.msg += "\n" + s +} + +func (l *Log) String() string { + return l.msg +} + +func (c *Customer) Log() *Log { + return c.log +} +``` + +输出: + + 1 - Yes we can! + 2 - After me the world will be a better place! + +相对的方式B可能会像这样: + +```go +package main + +import ( + "fmt" +) + +type Log struct { + msg string +} + +type Customer struct { + Name string + Log +} + +func main() { + c := &Customer{"Barak Obama", Log{"1 - Yes we can!"}} + c.Add("2 - After me the world will be a better place!") + fmt.Println(c) + +} + +func (l *Log) Add(s string) { + l.msg += "\n" + s +} + +func (l *Log) String() string { + return l.msg +} + +func (c *Customer) String() string { + return c.Name + "\nLog:" + fmt.Sprintln(c.Log) +} +``` + +输出: + + Barak Obama + Log:{1 - Yes we can! + 2 - After me the world will be a better place!} + +内嵌的类型不需要指针,Customer也不需要Add方法,它使用Log的Add方法,Customer有自己的String方法,并且在它里面调用了Log的String方法。 + +如果内嵌类型嵌入了其他类型,也是可以的,那些类型的方法可以直接在外层类型中使用。 + +因此一个好的策略是创建一些小的、可复用的类型作为一个工具箱,用于组成域类型。 + +** 10.6.7 多根继承 ## 链接 - [目录](directory.md)