2017-05-04 26 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。所有错误) )。