10.6.6 OK

This commit is contained in:
leisore
2015-08-11 14:40:37 +08:00
parent 42b7c21a7c
commit 1e467cfb71

View File

@@ -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)