html/text个模板内变量的命名空间是什么?我以为变量$x可以更改模板内的值,但这个示例告诉我我不能.

当我try 按年份分组比赛时,我失败了——大约是这样(http://play.golang.org/p/EX1Aut_ULD):

package main

import (
    "fmt"
    "os"
    "text/template"
    "time"
)

func main() {
    tournaments := []struct {
        Place string
        Date  time.Time
    }{
        // 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 .}}
    {{with .Date}}
        {{$year:=.Year}}
                    {{if ne $year $prev_year}}
                        Actions in year {{$year}}:
                {{$prev_year:=$year}}
            {{end}}
    {{end}}

        {{.Place}}, {{.Date}}
    {{end}}

    `)
    if err != nil {
        panic(err)
    }
    err = t.Execute(os.Stdout, tournaments)
    if err != nil {
        fmt.Println("executing template:", err)
    }
}

推荐答案

编辑:有关更新的答案,请参阅https://stackoverflow.com/a/52925780/1685538.


原始答案:

https://golang.org/pkg/text/template/#hdr-Variables:

变量的作用域扩展到控件的"End"操作 struct ("If"、"With"或"Range"),或设置为 如果没有这样的控制 struct ,则返回模板的末尾.

所以你用{{$prev_year:=$year}}定义的$prev_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)
    }
}

Go相关问答推荐

Kafka消费者在需要时不会暂停

Go在使用HTTP代理时如何处理DNS请求?

使用一元或服务器流将切片从GRPC服务器返回到客户端

如何使用Gio设置标题栏图标

无法使用exec从管道中读取.Go中的命令

如何为循环扫描的bufio scanner 设置超时?

Fizz对Gin的OpenAPI生成器正在重命名类型

如何将任何类型的数据值传递到 Golang 中的 GRPC Protobuf struct ?

Exchange Web 服务 - 使用 soap xml 请求查找所有未读邮件

将 struct 转换为 CSV 字符串

Go Colly 如何找到请求的元素?

Wire google Inject with multi return from provider 函数

如何将多个切片打印为一个切片?

在 GORM 中,如何在特定时区配置 autoCreateTime 和 autoUpdateTime?

自定义指标未显示在 prometheus web ui 中,grafana 中也是如此

vs 代码调试 go 测试不通过标志

GOLANG 如何使用 http.FileServer 从模板目录加载某个 html 文件

在 Go 中,为什么 exec.Command() 失败但 os.StartProcess() 成功启动winget.exe?

我应该明确地创建一个与Belongs To或Has Many对称的关系吗?

带有 *s3.S3 对象的 Golang 单元测试