Go 为什么IO.Writer不';你不能把听筒装满吗?
我正在测试一个模板生成工具。为此,我认为捕获模板执行输出的最简单方法是使用io编写器并在测试期间提供它。问题是由于某些原因,接收器没有使用模板输出“更新”。希望下面的代码能更好地解释我所面临的问题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
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()
,因为实现会写出传递给它的字节,所以不会丢失。