鉴于模板:
{{range $i, $e := .SomeField}}
{{if $i}}, {{end}}
$e.TheString
{{end}}
这可以输出:
one, two, three
但是,如果我要输出:
one, two, and three
我需要知道哪个是上面范围内的最后一个元素。
我可以设置一个变量来保存数组.SomeField
的长度,但是它总是3,并且上面的$i
值只会变为2.而且你不能在我看到的模板中执行算术运算。
是否可以检测模板范围中的最后一个值?干杯。
这可能不是最优雅的解决方案,但它是我能找到的最好的解决方案:
http://play.golang.org/p/MT91mLqk1s
package main
import (
"os"
"reflect"
"text/template"
)
var fns = template.FuncMap{
"last": func(x int, a interface{}) bool {
return x == reflect.ValueOf(a).Len() - 1
},
}
func main() {
t := template.Must(template.New("abc").Funcs(fns).Parse(`{{range $i, $e := .}}{{if $i}}, {{end}}{{if last $i $}}and {{end}}{{$e}}{{end}}.`))
a := []string{"one", "two", "three"}
t.Execute(os.Stdout, a)
}
注意:您也可以在不使用len
函数的情况下执行此操作(信用证给Russ Cox):http://play.golang.org/p/V94BPN0uKD
C.F.
今天我们在docker inspect命令中使用format时遇到了同样的问题。在没有修补Docker的情况下获取最后一个元素的最简单方法是(表达式已被拆分为多行以便于阅读):
{{ $image := "" }}
{{ range split .ContainerImageName "/" }}
{{ $image = . }}{{ end }}
{{ index (split $image ":") 0 }}
所以在我们的例子中,我们需要没有注册表地址和版本的图像名称。例如,像registry.domain.local / images / nginx:latest这样的图像名称变为nginx。
P.S:你需要Go> = 1.11来完成这项工作(https://github.com/golang/go/issues/10608)
P.P.S:问题是关于Go模板,但对于那些在这里遇到与Docker相同问题的配置示例:
1)在daemon.json
中使用Go模板
cat /etc/docker/daemon.json
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://127.0.0.1:20627",
"tag": "{{ $image := \"\" }}{{ range split .ContainerImageName \"/\" }}{{ $image = . }}{{ end }}{{ index (split $image \":\") 0 }}/{{.Name}}"
}
2)使用带有-f
选项的Go模板:
docker inspect \
-f '{{ $image := "" }}{{ range split .Config.Image "/" }}{{ $image = . }}{{ end }}{{ index (split $image ":") 0 }}' \
<container>