2017-07-20 4 views
-1

Ich versuche, meinen Kopf rund um das GoLang-System zu wickeln, und dort ein paar Dinge, die mich verwirren.Golang Typ Systeminkonsistenz (http-Paket)

Also habe ich an der http-Bibliothek gearbeitet, um zu versuchen, dies zu verstehen, und ich bin auf die folgenden, die keinen Sinn ergeben.

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

dies nicht über die Tatsache, dass die CONVERT-Funktion nicht benötigt wird, es ist die Tatsache, daß der Antworttext vom Typ io.closer ist und die ioutil.Readall nimmt eine io.reader, Aber ich kann es in einem Fall weitergeben, aber nicht in einem anderen. Gibt es etwas, das mir fehlt, das magisch passiert?

Ich weiß, dass die Schnittstelle des Lesers technisch näher kommt, da es die Read-Methode implementiert, aber das sollte sowohl in der Funktion als auch im Hauptteil wahr sein.

Jeder Einblick wäre großartig.

Dank

+1

Warum wollen Sie '' convert' io.Closer' zu akzeptieren, wenn es 'sein sollte io.Reader'? – bereal

+2

'ist die Tatsache, dass der Antworttext vom Typ io.closer' ... ist https://golang.org/src/net/http/response.go Der Text einer Antwort ist vom Typ' io.ReadCloser'. – Gavin

+0

Entschuldigung, ich habe einen kleinen Fehler gemacht, der Standardtyp des http body ist io.ReadCloser der aus dem Hauptpaket https://golang.org/pkg/net/http/#Response stammt. –

Antwort

2

es ist die Tatsache, dass die Antwort Körper vom Typ io.closer ist

Nein, es nicht ist. Erklärung der Request.Body ist http.Request:

Body io.ReadCloser 

Request.Body Das Feld ist vom Typ io.ReadCloser, es ist sowohl ein io.Reader und ein io.Closer.

Da es ein io.Reader (dynamischer Wert von Request.Body Arbeitsgeräte io.Reader) ist, kann man es verwenden/geben, wo ein io.Reader erforderlich ist, z.B. zu ioutil.ReadAll().

Da es auch implementiert io.Closer, können Sie auch übergeben, wo io.Closer erforderlich ist, wie Ihre convert() Funktion.

Aber innen wandeln die closer param io.Closer statischen Typ ist, können Sie nicht closer verwenden, wo ein in.Reader erforderlich ist. Es könnte sein (und in Ihrem Fall ist es), dass der dynamische Typ, der in closer gespeichert ist, auch io.Reader implementiert, aber es gibt keine Garantie dafür. Wie in diesem Beispiel:

Im obigen Beispiel closer innerhalb convert() einen Wert vom Typ mycloser, halten die wirklich nicht io.Reader nicht implementiert.

Wenn Ihr convert() Funktion seine Parameter zu behandeln beabsichtigt, auch als io.Reader, sollte der Parameter Typ io.ReadCloser sein:

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