Go编程语言接口概念的理解

3
我正在编写一个示例Http客户端/服务器代码,以了解更多关于Go的知识。在编写过程中,我需要读取响应正文。因此,我查看了Go Pkg文档http://golang.org/pkg/net/http/#Response并发现Body io.ReadCloser即Body是io.ReaderCloser类型。为了了解什么是io.ReaderCloser,我点击了超链接,发现http://golang.org/pkg/io/#ReadCloser是实现两个方法Reader和Closer的接口。看到这里,我认为我可以这样做。
line, _ , err := response.Body.Reader.ReadLine()

Go编译器给了我一个错误,说response.Body中没有Reader方法或类型。我认为从概念上讲,我不理解为什么不能这样做。也许我太过于按照Java的思维方式来思考了。如果有人能指出我的误解,我将不胜感激。

谢谢

1个回答

5

简而言之

Body 是一个 Reader,它本身并不包含 Reader。直接在 Body 上调用 Reader 方法即可。

详细解释

Go 接口简介:一组类型必须实现的方法,如果所有方法都被实现了,则该类型实现了该接口。

接下来是让你困惑的嵌入。如果我们有一个接口 Foo

type Foo interface {
    FooIt() error
}

我们希望有另一个接口,也使用方法FooIt+一些内容,我们可以像这样“嵌入”接口。

type FooPlusPlus interface {
    Foo // This embeds Foo in FooPlusPlus, making all of Foo's methods
        // part of FooPlusPlus's method pool.
    FooItAll() (bool, error)
}

嵌入提供了一种很好的方式来组合相关的接口,比如ReaderCloser。你可以有点像在Java世界中继承一样考虑它。你不需要显式地要求嵌入的接口,就像你不需要在Java子类中要求父类一样。
现在来实现FooPlusPlus
 type Demo int
 func (_ *Demo) FooIt() error {return nil}
 func (_ *Demo) FooItAll() (bool, error) {return false, nil}

现在,Demo是一个FooPlusPlus了。


所以 Body 一个 Reader,您可以直接从 Body 调用 Reader 方法,例如 response.Body.Read() - kibibu
嗯,好的,我觉得现在有意义了,因为io.ReadCloser实现了Reader和Closer接口,所以我可以直接使用response.Body.ReadLine()。 - tabiul
1
io.Reader只有一个方法:Read。我认为你看的是bufio.Reader,它有一个ReadLine方法。你可以通过bufio.NewReader从任何io.Reader中获取bufio.Reader:http://golang.org/pkg/bufio/#NewReader(我希望我没有把自己搞混并且没有犯错 :)) - Tyler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接