一个go interface 内嵌的问题

定义两个接口,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 .中看到这个原则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值