2017-05-04 19 views
6

Als Anfänger in Gehen Sie zu verstehen, ich habe Probleme io.Writer zu verstehen.io.Writer in Go - Anfänger versuchen, sie

Mein Ziel: eine Struktur nehmen und es in eine JSON-Datei schreiben.

Ansatz:
- encoding/json.Marshal verwenden, um meine Struktur in
Bytes zu konvertieren - füttern diese Bytes zu einem os.File Writer

Dies ist, wie ich es bekam Arbeit:

package main 

import (
    "os" 
    "encoding/json" 
) 

type Person struct { 
    Name string 
    Age uint 
    Occupation []string 
} 

func MakeBytes(p Person) []byte { 
    b, _ := json.Marshal(p) 
    return b 
} 

func main() { 
    gandalf := Person{ 
     "Gandalf", 
     56, 
     []string{"sourcerer", "foo fighter"}, 
    } 

    myFile, err := os.Create("output1.json") 
    if err != nil { 
     panic(err) 
    } 
    myBytes := MakeBytes(gandalf) 
    myFile.Write(myBytes) 
} 

Nach this article Lesen, ich änderte mein Programm so aus:

package main 

import (
    "io" 
    "os" 
    "encoding/json" 
) 

type Person struct { 
    Name string 
    Age uint 
    Occupation []string 
} 

// Correct name for this function would be simply Write 
// but I use WriteToFile for my understanding 
func (p *Person) WriteToFile(w io.Writer) { 
    b, _ := json.Marshal(*p) 
    w.Write(b) 
} 

func main() { 
    gandalf := Person{ 
     "Gandalf", 
     56, 
     []string{"sourcerer", "foo fighter"}, 
    } 

    myFile, err := os.Create("output2.json") 
    if err != nil { 
     panic(err) 
    } 
    gandalf.WriteToFile(myFile) 
} 

Meiner Meinung nach ist das erste Beispiel ist ein einfacher und leichter für einen Anfänger zu verstehen ... aber ich habe das Gefühl, dass das zweite Beispiel die Go idiomatische Weg der Erreichung des Ziels ist.

Fragen:
1. ist über Annahme korrekt (diese zweite Option ist Go idiomatic)?
2. Gibt es einen Unterschied in den oben genannten Optionen? Welche Option ist besser?
3. andere Möglichkeiten, dasselbe Ziel zu erreichen?

Danke,

WM

Antwort

6

Der Vorteil der zweiten Methode besteht darin, dass, wenn Sie eine Writer Schnittstelle sind vorbei, Sie etwas passieren kann, die Write implementiert - das ist nicht nur eine Datei aber ein http.ResponseWriter, zum Beispiel, oder stdout os.Stdout, ohne die Struct-Methoden zu ändern.

Sie können auf dem Paket io walkthrough diese handliche Blog-Post sehen. Der Autor macht den Fall, dass die Weitergabe als Parameterleser und -schreiber Ihren Code flexibler macht, zum Teil, weil so viele Funktionen die Schnittstellen Reader und Writer verwenden.

Wie Sie kommen mehr Gehen Sie zu verwenden, werden Sie feststellen, wie viel die Standard-Bibliothek auf Reader und Writer Schnittstellen lehnt, und wahrscheinlich kommen, um es zu schätzen :)

diese Funktion So (umbenannt):

// writes json representation of Person to Writer 
func (p *Person) WriteJson(w io.Writer) error { 
    b, err := json.Marshal(*p) 
    if err != nil { 
     return err 
    } 
    _, err = w.Write(b) 
    if err != nil { 
     return err 
    } 
    return err 
} 

schreiben würde zu einer Datei, http Antwort, ein des Benutzers Stdout oder sogar ein einfaches Byte Buffer; das Testen etwas einfacher zu machen.

Ich habe es umbenannt, weil was tut; das heißt, führt diese Funktion eine Person struct und:

  1. Marschälle die struct in eine json Darstellung
  2. Schreibt die json an einen Writer
  3. Returns Fehler von Rangier-/Schreiben
  4. entstehen

Noch eine Sache, Sie könnten verwirrt sein Was ein Writer ist, weil es kein Datentyp ist, sondern eher eine Schnittstelle - das ist ein Verhalten eines Datentyps, eine vordefinierte Methode, die ein Typ implementiert. Alles, was die Write() Methode implementiert, wird dann als ein Schreiber angesehen.

Dies kann ein wenig schwierig für Anfänger zu erfassen, aber es gibt viele Ressourcen online zu helfen, Schnittstellen zu verstehen (und ReadWriters sind einige der häufigsten Schnittstellen zu begegnen, zusammen mit Error() (ei. Alle Fehler)).