go - 在 Go 模板范围循环中,是否在每次迭代时重置循环外声明的变量?

标签 go go-templates

我正在尝试使用在 Go 模板范围循环外声明的变量来查看上一篇文章是否与当前文章发生在同一天。这是一个简化的示例。

其中 .Posts 是一个帖子结构数组,每个结构都有一个 .Content 和一个 .Date

{{ $prevDate := "" }}
{{ range $post := .Posts }}
    {{ if ne $prevDate $post.Date }}
        <div class="post-date">Posts dated: {{ $post.Date }}</div>
    {{ end }}
    <div class="post-content">{{ $post.Content }}</div>
    {{ $prevDate := $post.Date }}
{{ end }}

问题是 $prevDate 似乎在每次循环迭代开始时重置为 ""

任何人都可以帮助我理解为什么每次迭代都会重置 $prevDate 的值,并且可能会建议一种方法来完成我在这里尝试做的事情吗?

最佳答案

注意: Go 1.11 will support modifying template variables via assignment .这将是有效代码:

{{ $v := "init" }}
{{ if true }}
  {{ $v = "changed" }}
{{ end }}
v: {{ $v }} {{/* "changed" */}}

Go 1.11 之前的原始答案如下:


变量不会被重置。基本上,您在循环内重新声明了 $prevDate 变量。但它仅在重新声明之后和 {{range}} 的结束 {{end}} 标记之前的范围内。因此,当循环的下一次迭代到来时,您只会看到您没有更改的“外部”变量(因为您创建了一个新变量)。

您不能更改您创建的模板变量的值。

例如,您可以使用以下 range 形式:

{{ range $index, $post := .Posts }}

还有……

解决方案#1:注册函数

您可以为模板注册一个函数(参见 template.Funcs() ),您可以将 $index 传递给该函数,它将返回前一个元素的日期字段(在 $索引 -1).

它看起来像这样:

func PrevDate(i int) string {
    if i == 0 {
        return ""
    }
    return posts[i-1].Date
}

// Registering it:
var yourTempl = template.Must(template.New("").
    Funcs(map[string]interface{}{"PrevDate": PrevDate}).
    Parse(yourStringTemplate))

在您的模板中,您可以这样调用它:

{{range $index, $post := .Posts}}
    {{$prevDate := PrevDate $index}}
{{end}}

解决方案#2:使用帖子方法

这个解决方案是模拟的,但更简单:在您的 Posts 中添加一个方法,您可以直接调用它。无需注册函数。

例如:

type Post struct {
    // Your Post type
    Date string
}

type Posts []Post

func (p *Posts) PrevDate(i int) string {
    if i == 0 {
        return ""
    }
    return (*p)[i-1].Date
}

在您的模板中,您可以这样调用它:

{{range $index, $post := .Posts}}
    {{$prevDate := $.Posts.PrevDate $index}}
{{end}}

关于go - 在 Go 模板范围循环中,是否在每次迭代时重置循环外声明的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41163354/

相关文章:

docker - Gitlab CI/CD Runner 错误 : "unrecognized import path" GOLANG

image - 并行 Golang 中的 RGBA 到灰度

error-handling - Go 中如何指定和处理特定的错误?

go - 如何在 Go 模板中转义 “{{” 和 “}}” 分隔符?

go-templates - 如何在任何缩进级别放置带有多行输出的 go-template 操作?

regex - 去吧,正则表达式 : very challenging regex on Characters

Go 语言刮刀。如何抓取网站上动态生成的链接?

go - 带 Helm 的尺码表

go - text/template.Templates 和 html/template.Templates 之间的区别

go - 访问 slice Golang模板中的struct中的特定字段