Go io。围棋中的编剧-试图理解它们的初学者

Go io。围棋中的编剧-试图理解它们的初学者,go,writer,Go,Writer,作为围棋的初学者,我在理解io.Writer方面有问题 我的目标:获取一个结构并将其写入json文件 方法: -使用encoding/json.Marshal将我的结构转换为字节 -将这些字节馈送到os.FileWriter 我就是这样让它工作的: package main import ( "os" "encoding/json" ) type Person struct { Name string Age uint Occupation []str

作为围棋的初学者,我在理解
io.Writer
方面有问题

我的目标:获取一个结构并将其写入json文件

方法:
-使用
encoding/json.Marshal
将我的结构转换为字节
-将这些字节馈送到
os.File
Writer

我就是这样让它工作的:

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)
}
阅读后,我将程序更改为:

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)
}
在我看来,第一个例子是一个更简单,更容易理解的初学者。。。但我觉得第二个例子是实现目标的惯用方法

问题:
1.上述假设正确吗(第二个选项是惯用的)?
2.以上选项有区别吗?哪个选项更好?
3.实现相同目标的其他方法

谢谢,


WM

使用第二种方法的好处是,如果要传递一个
Writer
接口,则可以传递实现
Write
的任何东西,例如,它不仅是一个文件,而且是一个
http.ResponseWriter
,或者stdout
os.stdout
,而不改变结构方法

你可以在软件包上看到这篇便利的博客文章。作者认为,作为参数读取器和编写器传递会使代码更加灵活,部分原因是有太多函数使用
Reader
Writer
接口

随着您越来越多地使用Go,您会注意到标准库对
Reader
Writer
接口的依赖程度,并且可能会开始欣赏它:)

因此,此函数(重命名):

将写入文件、http响应、用户的标准输出,甚至是简单的字节缓冲区;使测试更加简单

我重新命名它是因为它做了什么;也就是说,此函数采用
Person
结构,并且:

  • 将结构封送到一个json表示中
  • 将json写入编写器
  • 返回因编组/写入而产生的任何错误

  • 还有一件事,您可能会对什么是编写器感到困惑,因为不是一种数据类型,而是一种接口——这是一种数据类型的行为,一种类型实现的预定义方法。因此,实现
    Write()
    方法的任何东西都被视为编写器

    这对于初学者来说一开始可能有点难掌握,但是有很多在线资源可以帮助他们理解界面(而
    ReadWriters
    是一些比较常见的界面,还有
    Error()
    (ei.all errors))

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