Go模板中的算术运算

huangapple go评论94阅读模式
英文:

Arithmetic in Go templates

问题

我正在尝试在Go模板中实现一个非常简单的功能,但是失败了!

range操作允许我遍历一个数组,并且可以得到它的从零开始的索引,代码如下:

{{range $index, $element := .Pages}}
  Number: {{$index}}, Text: {{$element}}
{{end}}

然而,我想要输出从1开始计数的索引。我的第一次尝试失败了:

Number: {{$index + 1}}

这会抛出一个illegal number syntax: "+"错误。

我查看了Go语言官方文档,没有找到关于模板内部的算术操作的特殊说明。

我漏掉了什么?

英文:

I am trying to achieve a very simple thing in a Go template and failing!

The range action allows me to iterate through an array along with its zero-based index, as so:

{{range $index, $element := .Pages}}
  Number: {{$index}}, Text: {{element}}
{{end}}

However, I am trying to output indices that start counting from 1. My first attempt failed:

Number: {{$index + 1}}

This throws an illegal number syntax: "+" error.

I looked into the go-lang official documentation and did not find anything particular regarding the arithmetic operation inside the template.

What am I missing?

答案1

得分: 56

你需要编写一个自定义函数来完成这个任务。

package main

import (
	"os"
	"text/template"
)

func main() {
	funcMap := template.FuncMap{
		// 函数名"inc"是在模板文本中调用该函数的名称。
		"inc": func(i int) int {
			return i + 1
		},
	}

	var strs []string
	strs = append(strs, "test1")
	strs = append(strs, "test2")

	tmpl, err := template.New("test").Funcs(funcMap).Parse(`{{range $index, $element := .}}
  Number: {{inc $index}}, Text:{{$element}}
{{end}}`)
	if err != nil {
		panic(err)
	}
	err = tmpl.Execute(os.Stdout, strs)
	if err != nil {
		panic(err)
	}
}

你可以在这个链接中查看代码:http://play.golang.org/p/WsSakENaC3

英文:

You have to write a custom function to do this.

http://play.golang.org/p/WsSakENaC3

package main

import (
	"os"
	"text/template"
)

func main() {
	funcMap := template.FuncMap{
		// The name "inc" is what the function will be called in the template text.
		"inc": func(i int) int {
			return i + 1
		},
	}

	var strs []string
	strs = append(strs, "test1")
	strs = append(strs, "test2")

	tmpl, err := template.New("test").Funcs(funcMap).Parse(`{{range $index, $element := .}}
  Number: {{inc $index}}, Text:{{$element}}
{{end}}`)
	if err != nil {
		panic(err)
	}
	err = tmpl.Execute(os.Stdout, strs)
	if err != nil {
		panic(err)
	}
}

答案2

得分: 20

如果你正在为consul-template编写Go模板,你可能会发现他们暴露的算术函数很有用:

数字:{{add $index 1}}
英文:

If you happen to be writing a Go template for use in consul-template, you may find their exposed arithmetic functions useful:

Number: {{add $index 1}}

答案3

得分: 6

请查看关于text/template内置函数的文档:

  • len可以从字符串中生成一个整数:{{ len "abc" }}
  • printf可以从整数生成给定长度的字符串:{{ printf "%*s" 3 "" }}
  • slice可以将字符串截断为给定长度:{{ slice "abc" 0 2 }}
  • slice可以将字符串截断给定长度:{{ slice "abc" 1 }}

你可以结合两者来增加一个整数:

{{ len (printf "a%*s" 3 "") }}

将会产生:

4

或者减少一个整数:

{{ len (slice (printf "%*s" 3 "") 1) }}

显示:

2

你还可以定义模板以重用模板的部分。

因此,我们可以使用模板定义带有1个参数的函数(请参见Go Playground上的示例):

{{ define "inc" }}{{ len (printf "%*s " . "") }}{{ end -}}
{{ define "op" }}{{.}} + 1 = {{ template "inc" . }}{{ end -}}
{{ template "op" 2 }}
{{ template "op" 5 }}

显示:

2 + 1 = 3
5 + 1 = 6

如果模板的输入是整数数组([]int{4, 2, 7}),我们可以进一步:

{{ define "inc" }}{{ len (printf "%*s " . "") }}{{ end -}}
{{ define "op" }}{{.}} + 1 = {{ template "inc" . }}{{ end -}}
{{- range . -}}
{{ template "op" . }}
{{ end -}}

请参见Go Playground上的完整示例

英文:

Check the documentation about the built-in functions of text/template:

  • len can produce an integer from a string: {{ len "abc" }}
  • printf can produce a string of a given length from an integer: {{ printf "%*s" 3 "" }}
  • slice can truncate a string to a given length from an integer: {{ slice "abc" 0 2 }}
  • slice can truncate a string by a given length from an integer: {{ slice "abc" 1 }}

You can combine both to increment an integer:

{{ len (printf "a%*s" 3 "") }}

will produce:

4

Or to decrement an integer:

{{ len (slice (printf "%*s" 3 "") 1) }}

shows:

2

You can also define templates to reuse pieces of templates.

So we can define 1 argument functions with templates (see on the Go Playground):

{{ define "inc" }}{{ len (printf "%*s " . "") }}{{ end -}}
{{ define "op" }}{{.}} + 1 = {{ template "inc" . }}{{ end -}}
{{ template "op" 2 }}
{{ template "op" 5 }}

shows:

2 + 1 = 3
5 + 1 = 6

We can go further if the input of the template is an array of integers ([]int{4, 2, 7}):

{{ define "inc" }}{{ len (printf "%*s " . "") }}{{ end -}}
{{ define "op" }}{{.}} + 1 = {{ template "inc" . }}{{ end -}}
{{- range . -}}
{{ template "op" . }}
{{ end -}}

See full example on the Go Playground.

答案4

得分: 2

这里还有一种方法可以创建一个HTML列表,但是这种方法并不适用于所有情况。

<ol>
{{range $index, $element := .Pages}}
  <li>Text: {{$element}}</li>
{{end}}
</ol>

它可以生成类似以下的内容:

  1. Text: Some page
  2. Text: Some different page
英文:

There's also way to just make a HTML list, however that won't fit for all cases.

&lt;ol&gt;
{{range $index, $element := .Pages}}
  &lt;li&gt;Text: {{$element}}&lt;/li&gt;
{{end}}
&lt;/ol&gt;

And it can produce something like that
<ol>
<li>Text: Some page </li>
<li>Text: Some different page </li>
</ol>

huangapple
  • 本文由 发表于 2014年9月5日 23:59:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/25689829.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定