包含与匿名组合
1.匿名组合
1.1 匿名组合定义
golang中组合语法,就是在一个类中,引入了另一个类,如
type Logger struct{
}
type Work struct{
log Logger
}
type Work2 struct{
log *Logger
}
func (Logger)Info(v ...interface{}){
}
如上边代码所示,Work类中定义了一个Logger类型的变量,这种是比较常见的引入方式,姑且在此称之为非匿名组合,那什么是匿名组合呢,如其名,就是在组合的过程中,不给名字呗,如代码所示:
type Logger struct {
}
type Work struct {
Logger
}
type Work2 struct {
*Logger
}
func (Logger) Info(v ...interface{}) {
}
上边的代码中,Work类与Work2类均与Logger类匿名组合。两个类唯一不同的是,Work2中组合的是指针类型的Logger类。
1.2 组合对象初始化
非匿名组合初始化方式
func main(){
var wk = Work{log:Logger{}}
var wwk = Work{Logger{}}
//...and so on
var wk2 = Work2{log:new(Logger)}
var wwk2 = Work2{new(Logger)}
//... and so on
}
匿名组合初始化
func main(){
var wk = Work{Logger{}}
var wwk = Work{Logger:Logger{}}
//... and so on
var wk2 = Work2{new(Logger)}
var wwk2 = Work2{Logger:&Logger{}}
//... and so on
}
上边是匿名组合常见的初始化方式。匿名组合后,被包含类得方法和属性可以直接被使用,即使是私有变量。
注意事项:
1.匿名组合多个类时,不同的类存在相同的方法,会不会冲突?答案是,不同的类中,不同的方法时不会冲突的,但是在调用这个方法时,需要明确是那个类中的方法,如果匿名组合进来的类得方法,与这个类主体中的方法发生冲突,那么默认情况下,会使用主体类中的方法。
2.匿名组合多个类时,类名相同,会不会冲突?答案是,会。就算包名不同,类名相同,也会冲突。
示例代码:
package main
import(
"bufio"
)
type Reader struct {
}
type Work4 struct {
Reader
bufio.Reader
}
上边代码编译时,会提示Reader重复定义 duplicate field Reader
原因在于,匿名组合中,没有给引入的类命名,所以默认采用了类名作为属性名。如上边wwk2这个对象在调用Logger的Info方法时,可以采用wwk2.Info(“hello”),也可以采用wwk2.Logger.Info(“hello”).
下边附上一段完整的演示代码,注意会报错哦,这段代码包含了上边的duplicate field Reader错误:
package main
import (
"bufio"
"fmt"
)
type Logger struct {
}
type Work struct {
Logger
}
type Work2 struct {
*Logger
}
type Work3 struct {
log *Logger
}
type Reader struct {
}
type Work4 struct {
Reader
bufio.Reader
}
func (Logger) Info(v ...interface{}) {
fmt.Println(v...)
}
func main() {
var wk = Work{Logger{}}
wk.Info("hello: Work{Logger{}}")
var wwk = Work{Logger: Logger{}}
wwk.Info("hello: Work{Logger: Logger{}}")
//... and so on
var wk2 = Work2{new(Logger)}
wk2.Info("hello: Work2{new(Logger)}")
var wwk2 = Work2{Logger: &Logger{}}
wwk2.Info("hello: Work2{Logger: &Logger{}}")
wwk2.Logger.Info("hello: wwk2.Logger.Info")
var wk3 = Work3{new(Logger)}
wk3.log.Info("hello: Work3{new(Logger)}")
}