为什么 IO.Writer 没有填充接收器?

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


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}}

`

http://play.golang.org/p/y4zWgyd5G1


阿晨1998
浏览 162回答 1
1回答

桃花长相依

您的stringer类型只是输入的“别名” *string。string在 Go 中是不可变的。您不应该使用 astring或指向 a 的指针来string构建模板的输出,因为您不能修改 a string,您只能创建一个新的(并丢弃旧的)。template.Execute()期待一个io.Writer. Write()输出的方法可能会被多次调用,并且您的stringer.Write()方法总是会丢弃之前写入它的数据。您可以通过始终将新数据连接到旧数据来修复它,如下所示:*s = *s + stringer(b)但是这个解决方案非常低效(它生成新string的并丢弃旧的)。一个更好且随时可用的替代方案是bytes.Buffer. 您可以创建一个字节缓冲区来实现这样的Writer接口:bytes.NewBuffer(nil)您不需要创建自己的stringer类型。在Go Playground上试试你修改过的程序。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go