一、前言
在很多地方我们会用到 io.Writer,比如下面是我在学习text/templat遇到的
str := "world"
tmpl, err := template.New("test").Parse("hello, {{.}}\n") //建立一个名字为test的模版"hello, {{.}}"
if err != nil{
panic(err)
}
err = tmpl.Execute(os.Stdout, str) //将str的值合成到tmpl模版的{{.}}中,并将合成得到的文本输入到os.Stdout,返回hello, world
if err != nil{
panic(err)
}
这里会在控制台上输出。一个 hello world。
其中是这个函数,把模版输出到 io.Writer中,这里是 os.Stdout,就是执行控制台。但当时就想在,如果需要输入到一个变量中怎么办呢,方便其他的函数调用,才发现对io.Writer不理解,不知道变量形式的io.Writer怎么弄。
func (t *Template) Execute(wr io.Writer, data any) error {
return t.execute(wr, data)
}
二、io.Writer介绍
这里我打开官方的 io.Writer,发现是一个接口,下面是它的注释
// Writer 是一个包含Write()方法的接口.
//
// Write() 写入 len(p) 长度的字节 从 p 到特定类型的字节流里
// Write()返回一个写入的字节长度,以及一个错误
// Write() 必须返回一个err,当len(p)<0的时候
// Write() 不能修改 p的数据。
//
// Implementations must not retain p.
type Writer interface {
Write(p []byte) (n int, err error)
}
io.Writer 会从 buf 中获取数据,然后再复制到底层数据流中,这里的底层数据流可能是文件、buffer或者网络响应。
看了上面的我们大约了解是一个 封装了Write()方法的一个接口。在开发中,常见的实现了io.Writer的接口,常见类型有啥呢?
三、常用的几种io.Writer实现
1、写入到内存中,bytes.Buffer
func TestBytes(t *testing.T) {
buf := new(bytes.Buffer)
// 写入到buf
buf.Write([]byte("hello"))
t.Log(buf.String())
//输出hello
}
2、写入界面输出中,os.Stdout
func TestOsStdout(t *testing.T) {
_, _ = os.Stdout.Write([]byte("hello"))
// 输出hello
// 和fmt.Println()打印一样,就是打印到控制台,
}
3、写入文件中
func TestFile(t *testing.T) {
f, err := os.Create("hi.txt")
defer f.Close()
if err != nil {
t.Fatal(err)
}
f.Write([]byte("hello"))
}
会发现,同目录下增加了一个 hi.txt,里面内容是hello
4、写入到自定义结构化数据中,这里用json
type Person struct {
Name string
Age int64
}
func (p *Person) Write(b []byte) (n int, err error) {
err = json.Unmarshal(b, p)
return 1, err
}
func TestStruct(t *testing.T) {
p := &Person{}
p.Write([]byte("{\n\"name\":\"hisheng\",\n\"age\":11\n}"))
t.Log(p.Name)
}
这里会输出hisheng
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。