【问题标题】:Golang Type system inconsistency (http package)Golang 类型系统不一致(http 包)
【发布时间】:2017-07-20 12:32:52
【问题描述】:

我正试图围绕 GoLang 类型系统展开思考,但有些地方让我感到困惑。

所以我一直在研究 http 库以试图理解这一点,我遇到了以下没有意义的内容。

package main

import (
    "net/http"
    "fmt"
    "io/ioutil"
    "io"
)

func convert(closer io.Closer) ([]byte) {
    body, _ := ioutil.ReadAll(closer);
    return body
}

func main() {

    client := &http.Client{}
    req, _ := http.NewRequest("GET", "https://www.google.com", nil)

    response, _ := client.Do(req);

    body, _ := ioutil.ReadAll(response.Body)

    fmt.Println(body);
    fmt.Println(convert(response.Body))

}

The Go Playground

这与不需要转换函数的事实无关,而是响应主体的类型为 io.closer 并且 ioutil.Readall 需要一个 io.reader,但我可以将它传入一个实例但不是如果在另一个。有没有什么我错过的神奇的事情发生了。

我知道,在实现 Read 方法时,在技术上更接近于通过读取器接口,但在函数和主体中都应该如此。

任何见解都会很棒。

谢谢

【问题讨论】:

  • 如果应该是io.Reader,你为什么要convert接受io.Closer?
  • is the fact that the response body is of type io.closer... golang.org/src/net/http/response.go Response 的主体是 io.ReadCloser 类型。
  • 对不起,我在这里犯了一个小错误,http body 的默认类型是 io.ReadCloser 这是来自主包golang.org/pkg/net/http/#Response。

标签: go types interface


【解决方案1】:

事实上,响应体是 io.closer 类型的

不,不是。 Request.Body 的声明在 http.Request:

Body io.ReadCloser

Request.Body 字段的类型为 io.ReadCloser,它既是 io.Reader 也是 io.Closer。

由于它是 io.Reader(Request.Body 的动态值实现 io.Reader),因此您可以在需要 io.Reader 的地方使用/传递它,例如到ioutil.ReadAll()。

由于它还实现了io.Closer,因此您也可以将它传递到需要io.Closer 的地方,就像您的convert() 函数一样。

但是在转换内部closer 参数有静态类型io.Closer,你不能在需要in.Reader 的地方使用closer。可能(在您的情况下是)存储在closer 中的动态类型也实现了io.Reader,但不能保证这一点。就像在这个例子中一样:

type mycloser int

func (mycloser) Close() error { return nil }

func main() {
    var m io.Closer = mycloser(0)
    convert(m)
}

在上面的示例中,convert() 中的 closer 将保存一个 mycloser 类型的值,它确实没有实现 io.Reader。

如果您的convert() 函数打算将其参数也视为io.Reader,则参数类型应为io.ReadCloser:

func convert(rc io.ReadCloser) ([]byte, error) {
    body, err := ioutil.ReadAll(rc)
    if err != nil {
        return body, err
    }
    err = rc.Close()
    return body, err
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2017-10-17
    • 2023-04-06
    相关资源
    最近更新 更多