我正在尝试使用在Go模板范围循环之外声明的变量,以查看先前的帖子是否与当前帖子在同一天发生。这是一个简化的示例。
哪里.Posts
有每个都有a .Content
和a 的post struct数组.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将支持通过Assignment修改模板变量
。这将是有效的代码:
{{ $v := "init" }}
{{ if true }}
{{ $v = "changed" }}
{{ end }}
v: {{ $v }} {{/* "changed" */}}
Go 1.11之前的原始答案如下:
变量不会重置。基本上发生的是$prevDate
在循环内重新声明变量。但这仅在重新声明之后和的结束{{end}}
标记之前{{range}}
。因此,在下一个循环迭代到来时,您只会看到未更改的“外部”变量(因为您创建了一个新变量)。
您无法更改创建的模板变量的值。
例如,您可以使用以下range
格式:
{{ range $index, $post := .Posts }}
和…
并且您可以为模板注册一个函数(请参阅参考资料template.Funcs()
),然后将其传递给$index
它,它将返回上一个元素的日期字段(位于$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}}
该解决方案是模拟的,但更简单:在您的方法中添加一个方法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}}
问题内容: 为什么以下工作正常? 但是据说这是危险的/不正确的: 是否需要在循环外声明变量? 问题答案: 局部变量的范围应始终尽可能小。 在你的例子我相信是不会使用的外while循环,否则你就不会问这个问题,因为它声明的内部while循环不会是一个选项,因为它不会编译。 所以,既然是不使用外循环,在尽可能小的范围是内 while循环。 所以,答案是着重那绝对应该被while循环内声明。没有,没有,
问题内容: ja块变量还是局部变量?我看到j的作用域只是直到for循环结束 问题答案: 局部变量在方法,构造函数或块中声明。 由此可见, 所有块变量都是局部变量。 按照块的定义 块是平衡括号之间的一组零个或多个语句,可以在允许单个语句的任何地方使用。 所以 无论在块内声明什么变量,范围都限于该块。 因此范围仅限于该块内部。那是循环。
问题内容: 我相信在AS3中,您应该在循环外初始化所有变量,以提高性能。JavaScript也是如此吗?哪个更好/更快/最佳实践? 要么 问题答案: 有 绝对没有区别 意义还是性能,在JavaScript或ActionScript。 是解析器的指令,而 不是 运行时执行的命令。如果在函数体(*)中的任何位置一次或多次声明了特定的标识符,则该标识符在块中的所有使用将引用局部变量。声明是在循环内部,循
问题内容: 我被困在我应该声明一个称为“ phrase”的字符串变量的部分,该变量不应一直循环播放。 让您知道我的任务是:与选项1相似,不同之处在于用户在输入第一队的结果后输入“ N”(而不是“ Q”)。然后,程序输入第二个团队名称及其结果,直到输入“ Q”。输出两个语句,例如选项1中的语句,然后输出第三条语句,该语句说明哪个团队处于第一位(基于点数) 输入样例: 样本输出: 更新 : 我的代码:
问题内容: 在Java中,我们不能与另一个具有相同名称的变量在同一作用域中声明一个变量: 语法错误,无法编译。但是,如果我们将其放入循环中: 不产生错误,效果很好。我们基本上是在声明相同的变量。是什么原因?在此背后我不知道/不了解的逻辑是什么? 问题答案: 考虑一下这种方式,在每个循环之后,作用域被“破坏”,变量消失了。在下一个循环中,将创建一个新的作用域,并且可以在该作用域中再次声明该变量。 由
问题内容: 在循环内部声明变量是否不好?在我看来,这样做,如下面的第一个代码块所示,将使用第二次的十倍的内存…由于在循环的每次迭代中都创建了一个新的字符串。这样对吗? 与 问题答案: 在循环内部声明变量是否不好? 一点也不!它将变量本地化到其使用点。 在我看来,如下面的第一个代码块所示,这样做将使用十倍于第二个内存的内存。 编译器可以优化内容以保持内存使用效率。仅供参考:如果您使用关键字告诉您变量