如何在Go模板中更新字段值

huangapple go评论133阅读模式
英文:

How to update field value in a Go template

问题

我有以下情况,我正在将包含映射的结构体传递给模板:

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "text/template"
  6. )
  7. var fns = template.FuncMap{
  8. "plus1": func(x int) int {
  9. return x + 1
  10. },
  11. }
  12. type codec struct {
  13. Names map[string]string
  14. Count int
  15. }
  16. func main() {
  17. a := map[string]string{"one": "1",
  18. "two": "2",
  19. "three": "3"}
  20. t := template.Must(template.New("abc").Funcs(fns).Parse(`{{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1 $.Count) $l}}{{$k}} {{$v}} {{end}}{{end}}.`))
  21. err := t.Execute(os.Stdout, codec{a, 0})
  22. if err != nil {
  23. log.Println(err)
  24. }
  25. }

我想要增加codecCount字段,以便我知道我已经看到了多少个映射项。

英文:

I have the following case, where I am passing a struct containing a map to a template:

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. "text/template"
  6. )
  7. var fns = template.FuncMap{
  8. "plus1": func(x int) int {
  9. return x + 1
  10. },
  11. }
  12. type codec struct {
  13. Names map[string]string
  14. Count int
  15. }
  16. func main() {
  17. a := map[string]string{"one": "1",
  18. "two": "2",
  19. "three": "3"}
  20. t := template.Must(template.New("abc").Funcs(fns).Parse(`{{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1 $.Count) $l}}{{$k}} {{$v}} {{end}}{{end}}.`))
  21. err := t.Execute(os.Stdout, codec{a, 0})
  22. if err != nil {
  23. log.Println(err)
  24. }
  25. }

I would like to increment the Count field of codec so that I can know how many items of the map I've seen.

答案1

得分: 2

一种解决方案是将plus1函数作为闭包,直接作用于codec的值:

// 首先创建一个codec实例
c := codec {a, 0}

// 现在将函数定义为闭包,并引用c
fns := template.FuncMap{
"plus1": func() int {
c.Count++
return c.Count
},
}

// 现在在模板中不需要传递任何参数给它
t := template.Must(template.New("abc").Funcs(fns).Parse({{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1) $l}}{{$k}} {{$v}} {{end}}{{end}}.))

输出结果为:

one 1 three 3

我猜这就是你的目标?并且该值在执行结束时保留在c中。

英文:

One solution is to make the plus1 function a closure that acts directly on the value of the codec:

  1. // first create a codec instance
  2. c := codec {a, 0}
  3. // now define the function as a closure with a reference to c
  4. fns := template.FuncMap{
  5. "plus1": func() int {
  6. c.Count++
  7. return c.Count
  8. },
  9. }
  10. // now we don't need to pass anything to it in the template
  11. t := template.Must(template.New("abc").Funcs(fns).Parse(`{{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1) $l}}{{$k}} {{$v}} {{end}}{{end}}.`))

The output was:

  1. one 1 three 3

which I'm guessing is what you were aiming for? And the value is retained in c at the end of execution.

答案2

得分: 1

你可以在你的结构体上简单地定义一个方法:

  1. type codec struct {
  2. Names map[string]string
  3. Count int
  4. }
  5. func (c *codec) IncAndGet() int {
  6. c.Count++
  7. return c.Count
  8. }

从模板中调用它:

  1. c := &codec{Count: 2}
  2. t := template.Must(template.New("").Parse(`{{.IncAndGet}} {{.IncAndGet}}`))
  3. t.Execute(os.Stdout, c)

输出结果(在Go Playground上尝试):

  1. 3 4

请注意,为了使其工作,该方法需要一个指针接收器(func (c *codec) IncAndGet()),并且你必须将指针传递给Template.Execute()(在我们的示例中,c是一个指针:c := &codec{Count: 2})。

如果你不想要任何结果,只想计数,可以将其定义为具有string返回类型并返回空字符串""

  1. func (c *codec) Inc() string {
  2. c.Count++
  3. return ""
  4. }
英文:

You can simply define a method on your struct:

  1. type codec struct {
  2. Names map[string]string
  3. Count int
  4. }
  5. func (c *codec) IncAndGet() int {
  6. c.Count++
  7. return c.Count
  8. }

Calling it from a template:

  1. c := &codec{Count: 2}
  2. t := template.Must(template.New("").Parse(`{{.IncAndGet}} {{.IncAndGet}}`))
  3. t.Execute(os.Stdout, c)

Output (try it on the <kbd>Go Playground</kbd>):

  1. 3 4

Note that for this to work, the method needs a pointer receiver (func (c *codec) IncAndGet()) and you have to pass a pointer to Template.Execute() (c is a pointer in our example: c := &amp;codec{Count: 2}).

If you don't want any result just counting, define it to have a string return type and return the empty string &quot;&quot;:

  1. func (c *codec) Inc() string {
  2. c.Count++
  3. return &quot;&quot;
  4. }

huangapple
  • 本文由 发表于 2016年1月27日 17:57:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/35034039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定