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

  • 写回答

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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面