【问题标题】:Join range block in go template在 go 模板中加入范围块
【发布时间】:2018-12-05 04:58:36
【问题描述】:

我有一个这样的 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。 或者是否有可能以某种方式将完整的范围块发送到某个自定义连接函数?

【问题讨论】:

    标签: json loops dictionary go go-templates


    【解决方案1】:

    这是一个如何使用模板的示例,但如果您想生成 JSON,我强烈建议使用第二种方法。

    坚持使用模板

    由于您在地图上进行测距,因此您不能(简单地)这样做。在切片的情况下,您可以检查索引变量(例如:Go template remove the last comma in range loop; 和 detect last item inside an array using range inside go-templates),但在地图的情况下,您不能这样做。

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

    这是一个示例实现:

    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"
        }
      ]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-30
      • 2021-09-16
      • 2013-07-04
      • 1970-01-01
      • 2018-11-25
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多