package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"strings"
)
type wr struct{}
func (w wr) Write(p []byte) (int, error) { //wr实现了Writer接口
fmt.Println("这里是w的write")
return 1, nil
}
func main() {
w := wr{}
r := strings.NewReader("some io.Reader stream to be read\n")
tee := io.TeeReader(r, w)
printall := func(r io.Reader) {
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
}
printall(tee)
}
结果是
下面是go标准文档的解释
——————————————————————————
func TeeReader
func TeeReader(r Reader, w Writer) Reader
TeeReader返回一个将其从r读取的数据写入w的Reader接口。所有通过该接口对r的读取都会执行对应的对w的写入。没有内部的缓冲:写入必须在读取完成前完成。写入时遇到的任何错误都会作为读取错误返回。
——————————————————————————
文档写了会执行w的写入,也就是w的write方法
这是io包里的源码,TeeReader函数返回的是teeReader,而teeReader实现了Reader接口,我就卡在这里无法理解为什么调用TeeReader,然后读取就会调用write方法?
然后我请教了大神,通过大神的话,我理解了原来是我不太理解接口的意义,和怎么用接口,接口是一组方法的组合,一组行为规范的定义。
teeReader实现了Reader接口,其他函数就可以接受Reader接口类型的参数,来调用Read方法,这里就是ReadAll接收teeReader这样的Reader接口类型的参数调用teeReader的Read方法。
我在找Go语言例子的时候发现了使用TeeReader实现简单的进度条下载,碰到了这个问题,小白现在才明白接口的意义,惭愧惭愧!