2015-04-03 90 views
-1

我想了解Go的接口和嵌入。去嵌入自定义接口

我想在这里做的是创建自己的自定义writerreader其中每一个执行要么io.Writerio.Reader

现在我想借此实现基本的接口,并将其嵌入到其他自定义这些自定义结构结构实现Read/Write/Close。下面的代码是我到目前为止,但是当我运行它,我得到以下错误

cannot use test (type MyReadWriteCloser) as type io.Writer in argument to fmt.Fprintf: MyReadWriteCloser does not implement io.Writer (missing Write method)

我想,当你嵌入另一个结构中的结构也得到了嵌入式结构的方法。有人能告诉我我错过了什么吗?

package main 

import (
"fmt" 
"io" 
) 

type MyWriter struct { 
    w io.Writer 
} 

func (m MyWriter) Write(b []byte) (n int, err error) { 
    // encrypt b and write to underlying writer 
    m.w.Write(b) 
    return 
} 

type MyReader struct { 
    r io.Reader 
} 

func (m MyReader) Read(b []byte) (n int, err error) { 
    // decrypt b 
    m.r.Read(b) 
    return 
} 

type MyReadWriteCloser struct { 
    MyWriter 
    MyReader 
} 

func (m MyReadWriteCloser) Close() error { 
    return nil 
} 

func main() { 
    fmt.Println("main start") 

    r, w := io.Pipe() 

    test := MyReadWriteCloser{ 
     MyWriter{w}, 
     MyReader{r}, 
    } 
    fmt.Fprintf(test, "hello world\n") 
} 

回答

0

你的语法错了,所以在接口/类型实际上并没有被嵌入。

type MyWriter struct { 
    w io.Writer 
} 

应该

type MyWriter struct { 
    io.Writer 
} 

而且根据我的理解正确的嵌入让你没有理由这样定义的方法;

func (m MyWriter) Write(b []byte) (n int, err error) { 
    m.w.Write(b) 
    return 
} 

因为身体只是m.Write(b),所以只是没有意义。如果嵌入类型,嵌入类型将能够直接从嵌入类型中调用方法(这与继承最接近,但对于偶然的读者来说它看起来是一样的)。如果嵌入类型中的方法或属性名称之间存在冲突,或者嵌入类型是嵌入类型,我不记得解决规则,但是一个好的经验法则是避免嵌入会导致命名冲突的类型,因为行为不会明显。

编辑: 示例如何重写基础类型中的方法并从中调用'基'(我引用一些地鼠可能会被这个词选择冒犯)

func (m MyWriter) Write(b []byte) (n int, err error) { 
    b = EncodeBFromMethodThatsInScopeHere(b) 
    return m.Writer.Write(b) 
} 

基本上,如果你想明确地使用嵌入式类型的方法,你可以使用嵌入式类型类型,就好像它是一个属性名称是指它作为类型的属性。

+0

我最终想做的一件事就是写一些东西给'MyReadWriteCloser',让MyWriter'加密我正在写的东西。我可以想象这种工作的唯一方式是编写自己的'Write'方法,并在我自定义的'Write'方法中调用底层编写器的'Write',这就是为什么我有'm.w.Write(b)'。如果我从结构中删除'w',那么我就没有办法(至少我不认为我这样做)写入底层的作者。希望这是有道理的,因为我一直在脑海中想着解决这个问题。对不起,如果我的术语是错误的。 – Jeff 2015-04-03 21:40:30

+0

@Jeff我将用一个例子来编辑,答案在这里http://stackoverflow.com/questions/20861786/golang-struct-calling-embedded-type-methods-when-method-has-been-overloaded – evanmcdonnal 2015-04-03 21:43:21

2

您不是在嵌入接口,而是在结构中创建它们的字段。

嵌入的样子:

type MyReader struct { 
    io.Reader 
} 

如果你想手动委托给接口,则需要使用相同的方法名

func (m MyReader) Read(b []byte) (n int, err error) { 
    return m.r.Read(b) 
}