Go 为什么IO.Writer不';你不能把听筒装满吗?

Go 为什么IO.Writer不';你不能把听筒装满吗?,go,Go,我正在测试一个模板生成工具。为此,我认为捕获模板执行输出的最简单方法是使用io编写器并在测试期间提供它。问题是由于某些原因,接收器没有使用模板输出“更新”。希望下面的代码能更好地解释我所面临的问题 package main import "fmt" import "text/template" type Company struct{ Name string } type Companies []Company func main() { s := new(string

我正在测试一个模板生成工具。为此,我认为捕获模板执行输出的最简单方法是使用io编写器并在测试期间提供它。问题是由于某些原因,接收器没有使用模板输出“更新”。希望下面的代码能更好地解释我所面临的问题

package main

import "fmt"
import "text/template"

type Company struct{
    Name string
} 

type Companies []Company

func main() {
    s := new(stringer)

    v := Companies{Company{Name:"Sony"}}
    tmp :=  template.Must(template.New("main").Parse(src))
    if err := tmp.Execute(s, v); err !=nil{
        panic(err)
    }
    if *s != "this is the header template"{
        fmt.Println("expected: \"this is the header template\" received: ", *s) 
    }else{
      fmt.Println("s is %v", *s)
    }
}

type stringer string
func (s *stringer)Write(b []byte)(int, error){
    *s = stringer(b)
    return len(b), nil
}

var src = `
 this is the header template
    {{range .}}

    {{.Name}}

    {{end}}
`

您的
stringer
类型只是
*string
类型的“别名”字符串是不可变的。您不应该使用
字符串
或指向
字符串
的指针来构建模板的输出,因为您不能修改
字符串
,只能创建一个新字符串(并丢弃旧字符串)

期待一个新的机会。输出的
Write()。您可以通过始终将新数据连接到旧数据来修复它,如下所示:

*s = *s + stringer(b)
bytes.NewBuffer(nil)
但是这个解决方案效率极低(它生成新的
字符串
s并丢弃旧的)

一个更好的、随时可用的替代方案是。您可以创建一个字节缓冲区,它实现
Writer
接口,如下所示:

*s = *s + stringer(b)
bytes.NewBuffer(nil)

您不需要创建自己的
stringer
类型。试试你修改过的程序。

我不确定我是否理解io.Writer的问题。我没有提供io.Writer吗?否则它不会编译,不是吗?@没有编辑答案的用户。您的
stringer.Writer()
方法可能会被多次调用,而您的实现总是会丢弃之前写入它的数据。明白了吗。。。我不知道它叫了好几次,所以整个误会。我想知道如果我想将输出写入文件,是否也应该使用缓冲区。起初我以为我可以给它一个*os.File()参数,但我想情况并非如此,因为它会像我的接收器那样截断文件内容,对吗?@userwithnothat No,将
文件
传递给
执行()
是完全正确的。无论调用多少次
File.Write()
,因为实现会写出传递给它的字节,所以不会丢失。