这是文章《如何在Go中使用模板》的第8部分(共14部分)。

	. . .
	funcMap := template.FuncMap{
		"dec": func(i int) int { return i - 1 },
	}
	var tmplFile = "lastPet.tmpl"
	tmpl, err := template.New(tmplFile).Funcs(funcMap).ParseFiles(tmplFile)
	if err != nil {
		panic(err)
	}
	. . .

首先,你正在声明一个FuncMap,它是一个函数映射:键是模板中可用的函数名称,值是函数本身。这里你有一个函数,dec,是一个匿名函数,在此提供是因为它非常简短。它接受一个整数,从中减去一,并返回结果。

然后你正在更改模板文件名称。最后,在调用ParseFiles之前,你将在调用之前插入对Template.Funcs的调用,并将刚刚定义的funcMap传递给它。在调用ParseFiles之前必须调用Funcs方法。

在运行代码之前,让我们了解一下模板中的范围操作所发生的情况。

最后一个宠物的模板:

{{- range (len . | dec | slice . ) }}

你正在获取你的狗的切片长度,将其传递给你的自定义减法函数减去一,然后将其作为第二个参数传递给前面讨论过的切片函数。所以对于一个三只狗的切片,range动作相当于{{- range (slice . 2) }}

保存 pets.go 并运行它。

go run pets.go
输出:

--- Name: Bruce Wayne Sex: Male (neutered) Age: 3 years, 8 months Breed: Chihuahua

看起来不错。如果你想展示最后两只狗而不只是最后一只,那该怎么办?编辑 lastPet.tmpl 文件,并在管道中再次调用 dec。

最后的宠物模板:

{{- range (len . | dec | dec | slice . ) }}
. . .

保存文件并再次运行pets.go。

go run pets.go
输出:

--- Name: Zephyr Sex: Male (intact) Age: 13 years, 3 months Breed: German Shepherd/Border Collie --- Name: Bruce Wayne Sex: Male (neutered) Age: 3 years, 8 months Breed: Chihuahua

你可以想象一下如何通过给dec函数传递一个参数并更改其名称来改进它,这样你就可以调用减2而不是dec | dec。

现在假设你想要以不同于斜杠的方式展示像Zephyr这样的混血狗。你不需要编写自己的函数来做到这一点,因为strings包中已经有一个函数可以实现这个目的,并且你可以从任何包中借用一个函数来在你的模板中使用。编辑pets.go文件,引入strings包并将其函数之一添加到funcMap中。

宠物出行