在Go模板范围循环中,是否在每次迭代时在循环重置之外声明变量? [英] In a Go template range loop, are variables declared outside the loop reset on each iteration?

查看:88
本文介绍了在Go模板范围循环中,是否在每次迭代时在循环重置之外声明变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用一个在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 变量。但它仅在重新声明之后的范围内以及 {{范围}} {{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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆