3 回答
TA贡献1851条经验 获得超4个赞
编辑:有关更新的答案,请参阅https://stackoverflow.com/a/52925780/1685538。
原答案:
https://golang.org/pkg/text/template/#hdr-Variables:
变量的范围扩展到声明它的控制结构(“if”、“with”或“range”)的“结束”操作,如果没有这样的控制结构,则扩展到模板的末尾。
所以$prev_year你定义的{{$prev_year:=$year}}只存在于.. 下一行 ( {{end}})。
似乎没有办法解决这个问题。
执行此操作的“正确”方法是从模板中取出该逻辑,并在 Go 代码中进行分组。
这是一个工作示例:https : //play.golang.org/p/DZoSXo9WQR
package main
import (
"fmt"
"os"
"text/template"
"time"
)
type Tournament struct {
Place string
Date time.Time
}
type TournamentGroup struct {
Year int
Tournaments []Tournament
}
func groupTournamentsByYear(tournaments []Tournament) []TournamentGroup {
if len(tournaments) == 0 {
return nil
}
result := []TournamentGroup{
{
Year: tournaments[0].Date.Year(),
Tournaments: make([]Tournament, 0, 1),
},
}
i := 0
for _, tournament := range tournaments {
year := tournament.Date.Year()
if result[i].Year == year {
// Add to existing group
result[i].Tournaments = append(result[i].Tournaments, tournament)
} else {
// New group
result = append(result, TournamentGroup{
Year: year,
Tournaments: []Tournament{
tournament,
},
})
i++
}
}
return result
}
func main() {
tournaments := []Tournament{
// for clarity - date is sorted, we don't need sort it again
{"Town1", time.Date(2015, time.November, 10, 23, 0, 0, 0, time.Local)},
{"Town2", time.Date(2015, time.October, 10, 23, 0, 0, 0, time.Local)},
{"Town3", time.Date(2014, time.November, 10, 23, 0, 0, 0, time.Local)},
}
t, err := template.New("").Parse(`
{{$prev_year:=0}}
{{range .}}
Actions in year {{.Year}}:
{{range .Tournaments}}
{{.Place}}, {{.Date}}
{{end}}
{{end}}
`)
if err != nil {
panic(err)
}
err = t.Execute(os.Stdout, groupTournamentsByYear(tournaments))
if err != nil {
fmt.Println("executing template:", err)
}
}
TA贡献1804条经验 获得超2个赞
在 go1.11 text/template 中,因此 html/template 变得能够设置现有变量的值,这意味着可以通过一个非常小的修改来使原始代码工作。
改变
{{$prev_year:=$year}}
到
{{$prev_year = $year}}
TA贡献1785条经验 获得超4个赞
正如this answer所述,该变量“重新分配”的范围以{{end}}块结束。因此,仅使用标准变量无法解决问题,应该在执行模板的 Go 程序中解决。
然而,在某些框架中,这并不容易(例如 protoc-gen-gotemplate)。
该小枝库增加了额外的功能,以标准的模板语言。其中之一是可变映射,可以通过以下方式使用:
// init the dictionary (you can init it without initial key/values as well)
{{$myVar := dict "key" "value"}}
// getting the "key" from the dictionary (returns array) and then fetching the first element from that array
{{pluck "key" $myVar | first}}
// conditional update block
{{if eq "some" "some"}}
// the $_ seems necessary because Go template functions need to return something
{{$_ := set $myVar "key" "newValue"}}
{{end}}
// print out the updated value
{{pluck "key" $myVar | first}}
这个小例子打印出来:
value
newValue
一种实用的方法是对所有可变变量使用单个字典,并将它们作为键存储在相应的变量名下。
参考:
http://masterminds.github.io/sprig/dicts.html
https://github.com/Masterminds/sprig
- 3 回答
- 0 关注
- 251 浏览
添加回答
举报