英文:
How to update field value in a Go template
问题
我有以下情况,我正在将包含映射的结构体传递给模板:
package main
import (
"log"
"os"
"text/template"
)
var fns = template.FuncMap{
"plus1": func(x int) int {
return x + 1
},
}
type codec struct {
Names map[string]string
Count int
}
func main() {
a := map[string]string{"one": "1",
"two": "2",
"three": "3"}
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}}.`))
err := t.Execute(os.Stdout, codec{a, 0})
if err != nil {
log.Println(err)
}
}
我想要增加codec
的Count
字段,以便我知道我已经看到了多少个映射项。
英文:
I have the following case, where I am passing a struct containing a map to a template:
package main
import (
"log"
"os"
"text/template"
)
var fns = template.FuncMap{
"plus1": func(x int) int {
return x + 1
},
}
type codec struct {
Names map[string]string
Count int
}
func main() {
a := map[string]string{"one": "1",
"two": "2",
"three": "3"}
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}}.`))
err := t.Execute(os.Stdout, codec{a, 0})
if err != nil {
log.Println(err)
}
}
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
:
// first create a codec instance
c := codec {a, 0}
// now define the function as a closure with a reference to c
fns := template.FuncMap{
"plus1": func() int {
c.Count++
return c.Count
},
}
// now we don't need to pass anything to it in the template
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:
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
你可以在你的结构体上简单地定义一个方法:
type codec struct {
Names map[string]string
Count int
}
func (c *codec) IncAndGet() int {
c.Count++
return c.Count
}
从模板中调用它:
c := &codec{Count: 2}
t := template.Must(template.New("").Parse(`{{.IncAndGet}} {{.IncAndGet}}`))
t.Execute(os.Stdout, c)
输出结果(在Go Playground上尝试):
3 4
请注意,为了使其工作,该方法需要一个指针接收器(func (c *codec) IncAndGet()
),并且你必须将指针传递给Template.Execute()
(在我们的示例中,c
是一个指针:c := &codec{Count: 2}
)。
如果你不想要任何结果,只想计数,可以将其定义为具有string
返回类型并返回空字符串""
:
func (c *codec) Inc() string {
c.Count++
return ""
}
英文:
You can simply define a method on your struct:
type codec struct {
Names map[string]string
Count int
}
func (c *codec) IncAndGet() int {
c.Count++
return c.Count
}
Calling it from a template:
c := &codec{Count: 2}
t := template.Must(template.New("").Parse(`{{.IncAndGet}} {{.IncAndGet}}`))
t.Execute(os.Stdout, c)
Output (try it on the <kbd>Go Playground</kbd>):
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 := &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
""
:
func (c *codec) Inc() string {
c.Count++
return ""
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论