dongshao5573
2015-02-04 12:28
浏览 21
已采纳

为什么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

图片转代码服务由CSDN问答提供 功能建议

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

 包main 
 
import“ fmt” 
import“ text / template” 
 
type Company struct {  
名称字符串
} 
 
type公司[]公司
 
func main(){
s:= new(stringer)
 
v:=公司{Company {名称:“ Sony”}}} 
  tmp:= template.Must(template.New(“ main”)。Parse(src))
如果err:= tmp.Execute(s,v);  err!= nil {
 panic(err)
} 
如果* s!=“这是标题模板” {
 fmt.Println(“期望:\”这是标题模板\“收到:”  ,* s)
} else {
 fmt.Println(“ s is%v”,* s)
} 
} 
 
type stringer string 
func(s * stringer)Write(b [] byte  )(int,错误){
 * s =字符串(b)
返回len(b),nil 
} 
 
var src =`
这是标头模板
 {{range。}}  
 
 {{.Name}} 
 
 {{end}} 
` 
   
 
 

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

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • duanqian1888 2015-02-04 12:33
    已采纳

    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.

    已采纳该答案
    评论
    解决 无用
    打赏 举报