为什么IO.Writer无法填充接收器?

I'm trying to test a template generation tool. In order to do this I was thinking that the easiest way to capture the template execution output is to use a io writer and provide it during testing. The issue is that for some reasons the receiver is not "updated" with the template output. Hopefully the code below explains better the issue I'm facing.

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

Your stringer type is just an "alias" to *string type. string in Go is immutable. You shouldn't use a string or a pointer to a string to build the the output of a template, because you can't modify a string, you can only create a new (and throw away the old one).

template.Execute() expects an io.Writer. The Write() method of the output might be called multiple times, and your stringer.Write() method always throws away data written to it earlier. You could fix it by always concatenating the new data to the old like this:

*s = *s + stringer(b)

But this solution is terribly inefficient (it generates new strings and throws away old ones).

A much better and ready-to-use alternative is bytes.Buffer. You can create a byte buffer which implements the Writer interface like this:

bytes.NewBuffer(nil)

You don't need to create your own stringer type. Try your modified program on Go Playground.