在Go模板中加入范围块 [英] Join range block in go template

查看:94
本文介绍了在Go模板中加入范围块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的go模板:

I have a go template like this:

 "environment": [
   {{- range $k,$v := .env }}
     {
       "name": "{{ $k }}",
       "value": "{{ $v }}"
     },
   {{- end }}
   ]

我在下面得到输出:

     "environment": [
    {
      "name": "name",
      "value": "test"
    },
    {
      "name": "region",
      "value": "us-east-1"
    },
  ]

并且我想像下面这样渲染它:

and i want to render it like below:

    "environment": [
    {
      "name": "name",
      "value": "bxbd"
    },
    {
      "name": "region",
      "value": "us-east-1"
    }
  ]

我无法摆脱最后一个逗号来制作有效的json. 还是有可能以某种方式将完整的范围块发送给某些自定义联接功能?

I am not able to get rid of the last comma to make valid json. Or is it possible to somehow send the complete range block to some custom join function?

推荐答案

以下是使用模板的示例,但是如果要生成JSON,我强烈建议使用第二种方法.

Here's an example how to do it with templates, but I strongly recommend to use the 2nd approach if you want to generate JSON.

由于您在地图上范围很广,因此您无法(简单地)做到这一点.如果是切片,您可以检查index变量(例如:转到模板删除范围循环中的最后一个逗号;然后

Since you're ranging over a map, you can't (simply) do it. In case of slices you could check the index variable (examples: Go template remove the last comma in range loop; and detect last item inside an array using range inside go-templates), but in case of maps you can't do that.

知道您是否处于第一个(或最后一个)迭代是一个状态,您必须维护自己.例如,为此使用自定义函数或方法.

Knowing if you're at the first (or last) iteration is a state which you must maintain yourself. And example is to use custom functions or methods for this.

这是一个示例实现:

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)
    }
}

输出(在游乐场上尝试):

"environment": [
     {
       "name": "name",
       "value": "test"
     },
     {
       "name": "region",
       "value": "us-east-1"
     }
   ]

使用encoding/json生成JSON

如果您的目标是生成JSON,则应使用 encoding/json 包以生成有效的JSON文档.上面的模板不了解JSON语法和上下文,并且映射条目的值在写入输出时不会转义,因此您仍然可能得到无效的JSON.

Use encoding/json to generate JSON

If you're goal is to generate JSON, you should use the encoding/json package to generate valid JSON document. The above template has no knowledge about JSON syntax and context, and the values of the map entries are not escaped when written to the output, so you may still end up with invalid JSON.

最好是这样生成JSON:

Best would be to generate the JSON like this:

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)
    }
}

输出(在游乐场上尝试):

{
  "environment": [
    {
      "name": "name",
      "value": "test"
    },
    {
      "name": "region",
      "value": "us-east-1"
    }
  ]
}

这篇关于在Go模板中加入范围块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆