在Go模板范围循环中,是否在每次迭代时在循环重置之外声明变量? [英] In a Go template range loop, are variables declared outside the loop reset on each iteration?
问题描述
我试图使用一个在Go模板范围循环之外声明的变量来查看前一篇文章是否与当前文章同一天发生。这里有一个简单的例子。
其中 .Posts
是一个数组结构,每个结构都有一个 .Content
和a .Date
。
{{$ prevDate:=}}
{{range $ post:= .Posts}}
{{if ne $ prevDate $ post.Date}}
< div class =post-date>发布日期:{{$ post.Date}}< / div>
{{end}}
< div class =post-content> {{$ post.Content}}< / div>
{{$ prevDate:= $ post.Date}}
{{end}}
问题是,在每次迭代开始时, $ prevDate
似乎重置为
任何人都可以帮助我理解为什么 $ prevDate
的值在每次迭代时都被重置,一种方法来完成我在这里要做的事情?
变量不会被重置。基本上发生的是,你重新声明循环内的 $ prevDate
变量。但它仅在重新声明之后的范围内以及 {{范围}} $ c $的结束
{{end}}
标记之前C>。所以当循环的下一个迭代到来时,你只能看到你没有改变的外部变量(因为你创建了一个新的变量)。
你可以做的是例如使用下面的范围
表格:
{{range $ index,$ post:= .Posts}}
和...
解决方案#1:带注册功能
您可以为模板注册一个函数(参见
template.Funcs()
),您可以向其传递$ index
并返回前一个元素的日期字段(在$ index -1
)。
它看起来像这样:
func PrevDate(i int)string {
if i == 0 {
return
}
返回职位[i-1] .Date
}
//注册:
var yourTempl = template.Must(template.New()。
Funcs(map [string] interface {} {PrevDate:PrevDate})。
Parse(yourStringTemplate))
从模板中可以调用它:
{{range $ index,$ post:= .Posts}}
{{$ prevDate:= PrevDate $ index} }
{{end}}
解决方案2: h2>
这个解决方案是模拟的,但更简单:向
Posts
添加一个方法,您可以直接调用它。
例如:
类型Post struct {
// Your Post type
日期字符串
}
类型文章[] 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}}
I'm trying to use a variable declared outside a Go template range loop to see if the previous post occurred on the same day as the current post. Here's a simplified example.
Where
.Posts
is an array of post structs that each have a.Content
and a.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 }}
The problem is that
$prevDate
seems to be reset to""
at the start of each iteration of the loop.Can anyone help me understand why the value of
$prevDate
is reset on each iteration and perhaps suggest a way to accomplish what I'm trying to do here?解决方案Variables are not reset. Basically what happens is that you redeclare the
$prevDate
variable inside the loop. But it is only in scope after the redeclaration and before the closing{{end}}
tag of the{{range}}
. So when the next iteraiton of the loop comes, you only see the "outer" variable which you haven't changed (because you created a new).You can't change the values of the template variables you create.
What you can do is for example use the following
range
form:{{ range $index, $post := .Posts }}
And...
Solution #1: with a registered Function
And you can register a function for the template (see
template.Funcs()
) to which you can pass the$index
and it would return the date field of the previous element (at$index -1
).It would look something like this:
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))
And from your template you can call it like:
{{range $index, $post := .Posts}} {{$prevDate := PrevDate $index}} {{end}}
Solution #2: with a Method of Posts
This solution is analog but is even simpler: add a method to your
Posts
and you can call it directly. No need to register a function.For example:
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 }
And from your template you can call it like:
{{range $index, $post := .Posts}} {{$prevDate := $.Posts.PrevDate $index}} {{end}}
这篇关于在Go模板范围循环中,是否在每次迭代时在循环重置之外声明变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!