我正在尝试实现一个满足 io.Writer 要求的代理,因此我可以将其插入记录器。这个想法是它会像平常一样打印输出,但也会保留一份数据副本供以后读取。
以下代码中的 ProxyIO 结构应该执行此操作,而且只要我直接调用其 Write() 方法,它确实会执行此操作。但是,当我将它插入 log.Logger 实例时,输出是意外的。
(这是精简代码,我想使用的原始实现是使用映射和循环指针,而不是[][]byte
示例代码中使用的 buf。我还删除了所有锁定。)
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
)
type ProxyIO struct {
out io.Writer // the io we are proxying
buf [][]byte
}
func newProxyIO(out io.Writer) *ProxyIO {
return &ProxyIO{
out: out,
buf: [][]byte{},
}
}
func (r *ProxyIO) Write(s []byte) (int, error) {
r.out.Write(s)
r.buf = append(r.buf, s)
return len(s), nil
}
func main() {
p := newProxyIO(ioutil.Discard)
p.Write([]byte("test1\n"))
p.Write([]byte("test2\n"))
p.Write([]byte("test3\n"))
l := log.New(p, "", 0)
l.Print("test4")
l.Print("test5")
l.Print("test6")
for i, e := range p.buf {
fmt.Printf("%d: %s", i, e)
}
}
(这里是操场上的代码https://play.golang.org/p/UoOq4Nd-rmI)
我希望这段代码有以下输出:
0: test1
1: test2
2: test3
3: test4
4: test5
5: test6
但是,它将始终打印:
0: test1
1: test2
2: test3
3: test6
4: test6
5: test6
我的地图实现的行为是相同的。我还尝试使用双向链表作为container/list存储,它总是一样的。所以我一定在这里遗漏了一些重要的东西。
为什么我在缓冲区中看到了三次最后的日志输出,而不是最后三行日志输出?
catspeake
相关分类