2017-05-04 73 views
6

作爲Go的初學者,我在理解io.Writer時遇到了問題。io.Writer in Go - 試圖理解它們的初學者

我的目標:採取一個結構並將其寫入一個json文件。

方法:
- 使用encoding/json.Marshal到我的結構轉換爲字節
- 喂這些字節到os.File作家

這是我如何得到它的工作:

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) 
} 

閱讀this article後,我改變了我的程序:

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) 
} 

在我看來,第一個例子對初學者來說更簡單易懂,但我認爲第二個例子是達到目標的Go慣用方式。

問題:
1.以上假設是否正確(即第二個選項是Go idiomatic)?
2.上述選項有差異嗎?哪個選項更好?
3.其他方式實現相同的目標?

謝謝

WM

回答

6

使用第二種方法的好處是,如果你傳遞一個Writer接口,你可以通過任何其中實現Write - 不僅是一個文件但是例如http.ResponseWriter或stdout os.Stdout,而不更改結構方法。

你可以在包io walkthrough上看到這個方便的博客文章。作者通過參數讀者和作者使得您的代碼更加靈活,部分原因是因爲如此多的函數使用了接口ReaderWriter

至於你來使用Go越多,你會發現標準庫有多少斜靠在ReaderWriter接口,而且很可能來欣賞吧:)

所以這個功能(改名):

// 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 
} 

會寫入一個文件,HTTP響應,用戶的標準輸出,甚至一個簡單的字節的緩衝區;使測試更簡單一些。

我改名了,因爲做了什麼;也就是說,該功能需要一個Person結構和:

  1. 法警的結構爲JSON表示
  2. 寫JSON從編組產生的任何錯誤,一個Writer
  3. 返回/寫

還有一件事,您可能會感到困惑什麼作家是,因爲它是不是數據類型,而是接口 - 這是一種數據類型的行爲,一種類型實現的預定義的方法。任何實現Write()方法的東西都被認爲是一個作家。

這可有點困難初學者先掌握,但也有很多的在線幫助理解接口(和ReadWriters是一些比較常見的接口遇到資源,與Error()沿(EI。所有錯誤) )。