为什么 IO.Writer 没有填满接收器?
Why the IO.Writer doesn't fill the receiver?
我正在尝试测试模板生成工具。为了做到这一点,我认为捕获模板执行输出的最简单方法是使用 io writer 并在测试期间提供它。问题是由于某些原因,接收者没有 "updated" 模板输出。希望下面的代码能更好地解释我面临的问题。
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
类型只是 "alias" 到 *string
类型。 string
在 Go 中是不可变的。您不应该使用 string
或指向 string
的指针来构建模板的输出,因为您无法修改 string
,您只能创建一个新的 (扔掉旧的)。
template.Execute()
expects an io.Writer
。输出的 Write()
方法可能会被调用多次,而您的 stringer.Write()
方法总是会丢弃之前写入的数据。您可以通过始终将新数据连接到旧数据来修复它,如下所示:
*s = *s + stringer(b)
但是这个解决方案非常低效(它生成新的 string
并丢弃旧的)。
更好的即用型替代方案是 bytes.Buffer
。您可以创建一个实现 Writer
接口的字节缓冲区,如下所示:
bytes.NewBuffer(nil)
您不需要创建自己的 stringer
类型。在 Go Playground.
上尝试修改后的程序
我正在尝试测试模板生成工具。为了做到这一点,我认为捕获模板执行输出的最简单方法是使用 io writer 并在测试期间提供它。问题是由于某些原因,接收者没有 "updated" 模板输出。希望下面的代码能更好地解释我面临的问题。
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
类型只是 "alias" 到 *string
类型。 string
在 Go 中是不可变的。您不应该使用 string
或指向 string
的指针来构建模板的输出,因为您无法修改 string
,您只能创建一个新的 (扔掉旧的)。
template.Execute()
expects an io.Writer
。输出的 Write()
方法可能会被调用多次,而您的 stringer.Write()
方法总是会丢弃之前写入的数据。您可以通过始终将新数据连接到旧数据来修复它,如下所示:
*s = *s + stringer(b)
但是这个解决方案非常低效(它生成新的 string
并丢弃旧的)。
更好的即用型替代方案是 bytes.Buffer
。您可以创建一个实现 Writer
接口的字节缓冲区,如下所示:
bytes.NewBuffer(nil)
您不需要创建自己的 stringer
类型。在 Go Playground.