我有一个像这样的 go 模板:
"environment": [
{{- range $k,$v := .env }}
{
"name": "{{ $k }}",
"value": "{{ $v }}"
},
{{- end }}
]
我得到以下输出:
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
},
]
我想像下面这样渲染它:
"environment": [
{
"name": "name",
"value": "bxbd"
},
{
"name": "region",
"value": "us-east-1"
}
]
我无法摆脱最后一个逗号来制作有效的 json。 或者是否有可能以某种方式将完整的范围 block 发送到某个自定义连接函数?
最佳答案
这是一个如何使用模板来完成的示例,但如果您想生成 JSON,我强烈建议使用第二种方法。
坚持使用模板
由于您是在 map 上测距,因此您不能(简单地)这样做。对于 slice ,您可以检查索引变量(示例:Go template remove the last comma in range loop ;和 detect last item inside an array using range inside go-templates),但对于 map ,您不能这样做。
知道您是否处于第一次(或最后一次)迭代是您必须自己维护的状态。例如,为此使用自定义函数或方法。
这是一个示例实现:
type Params struct {
Env map[string]string
Counter int
}
func (p *Params) IncMore() bool {
p.Counter++
return p.Counter < len(p.Env)
}
const src = `"environment": [
{{- range $k,$v := .Env }}
{
"name": "{{ $k }}",
"value": "{{ $v }}"
}{{if $.IncMore}},{{end}}
{{- end }}
]`
测试它:
func main() {
t := template.Must(template.New("").Parse(src))
p := &Params{
Env: map[string]string{
"name": "test",
"region": "us-east-1",
},
}
err := t.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
输出(在 Go Playground 上尝试):
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
}
]
使用encoding/json
生成JSON
如果您的目标是生成 JSON,您应该使用 encoding/json
包生成有效的 JSON 文档。上面的模板不了解 JSON 语法和上下文,映射条目的值在写入输出时不会转义,因此您最终可能仍会得到无效的 JSON。
最好是像这样生成 JSON:
type Entry struct {
Name string `json:"name"`
Value string `json:"value"`
}
type Params struct {
Env []Entry `json:"environment"`
}
func main() {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ") // Optional
p := &Params{
Env: []Entry{
{Name: "name", Value: "test"},
{Name: "region", Value: "us-east-1"},
},
}
err := enc.Encode(p)
if err != nil {
panic(err)
}
}
输出(在 Go Playground 上尝试):
{
"environment": [
{
"name": "name",
"value": "test"
},
{
"name": "region",
"value": "us-east-1"
}
]
}
关于json - 在 go 模板中加入范围 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51043433/