定义两个接口,Reader Writer,分别有自己的Read和Write方法,
再定义一个结构体,ReadWriter,内嵌了这两种接口
再定义个Robot结构体,实现两个接口中的方法,
问 如何初始化一个ReadWriter类型的变量??
type Reader interface {
Read() (c string, err error)
}
type Writer interface {
Write(p string) (n int, err error)
}
type ReadWriter struct {
reader *Reader
writer *Writer
}
type Robot struct {
content string
}
func (fc *Robot) Write(p string) (n int, err error) {
fc.content = string(p)
return len(p), nil
}
func (fc *Robot) Read() (c string, err error) {
return fc.content, nil
}
func main() {
var rw = ReadWriter{}
//rw.writer = Writer(Robot{})
//rw.reader = Reader(Robot{})
fmt.Println(rw.writer)
}
等我想通了 再来更新
想明白了 出在我内嵌的方式有问题
type ReadWriter struct {
reader *Reader //*Reader of ReadWriter type 这种不叫内嵌接口类型 而是内嵌指针了
writer *Writer
}
以下为正确的内嵌:
type Reader interface {
Read() (c string, err error)
}
type Writer interface {
Write(p string) (n int, err error)
}
type ReadWriter struct {
reader Reader
writer Writer
}
func (rw *ReadWriter) Read() (c string, err error) {
return rw.reader.Read()
}
func (rw *ReadWriter) Write(p string) (n int, err error) {
return rw.writer.Write(p)
}
这要求初始化时ReadWriter结构体的变量时,已经有一个实现了 Reader和Writer接口的结构体,
type Robot struct {
content string
}
func (fc *Robot) Write(p string) (n int, err error) {
fc.content = string(p)
return len(p), nil
}
func (fc *Robot) Read() (c string, err error) {
return fc.content, nil
}
type Kid struct {
content string
}
func (fc *Kid) Write(p string) (n int, err error) {
fc.content = p
return len(p), nil
}
func (fc *Kid) Read() (c string, err error) {
return fc.content, nil
}
此时再初始化ReaderWriter变量:
func main() {
rb := Robot{}
var rw = ReadWriter{&rb, &rb}
rw.Write("i am robot")
fmt.Println(rw.Read())
rw.reader = &Kid{"i am kid"}
fmt.Println(rw.Read())
}
这才是 我要的结构体内嵌接口类型的正确打开方式,
那么问题来了,如果我非要内嵌一个 接口类型的指针呢?就像我最开始写的那样,
type ReadWriter struct {
reader *Reader //*Reader of ReadWriter type
writer *Writer
}
代码改写:
type Reader interface {
Read() (c string, err error)
}
type Writer interface {
Write(p string) (n int, err error)
}
type ReadWriter struct {
reader *Reader
writer *Writer
}
func (rw *ReadWriter) Read() (c string, err error) {
return (*rw.reader).Read() //按照C++的理解 是先对指针解引用,再用Reader类型对象打点调用其方法Read()
}
func (rw *ReadWriter) Write(p string) (n int, err error) {
return (*rw.writer).Write(p)
}
type Robot struct {
content string
}
func (fc *Robot) Write(p string) (n int, err error) {
fc.content = string(p)
return len(p), nil
}
func (fc *Robot) Read() (c string, err error) {
return fc.content, nil
}
func main() {
rb := Robot{}
var reader Reader = &rb
var writer Writer = &rb
var rw = ReadWriter{&reader, &writer}
rw.Write("i am robot")
fmt.Println(rw.Read())
}
两种定义方式的代码功能是一样的,非要引用接口类型,反而使代码更难理解了 没有必要!
今天偶在GitHub - xxjwxc/uber_go_guide_cn: Uber Go 语言编码规范中文版. The Uber Go Style Guide .中看到这个原则