簡體   English   中英

在Go文本模板中遍歷地圖

[英]Iterate through map in Go text template

我有一個如下的值map

vals := map[string]interface{}{"foo": 1, "bar": 2, "baz": 7}
data := map[string]interface{}{"bat": "obj", "values": vals}

我的模板應該如何生成以下字符串(注意正確的逗號用法)?

SET obj.foo=1, obj.bar=2, obj.baz=7

我以此為模板開始:

SET {{range $i, $v := .values}} {{.bat}}.{{$i}}={{$v}},{{end}}

但這只是打印出來

SET

即使這樣做確實可行,逗號也不正確。 然后,我嘗試使用自定義函數來格式化地圖,但是我無法獲得模板來調用我的函數。 以下各項似乎都不起作用:

SET {{.MyFunction .values}}
SET {{call .MyFunction .values}}
SET {{call MyFunction .values}}

當MyFunction定義為:

func MyFunction(data map[string]interface{}) string {
  fmt.PrintLn('i was called!')
  return "foo"
}

我正在使用如下所示的輔助函數執行模板:

func useTemplate(name string, data interface{}) string {
  out := new(bytes.Buffer)
  templates[name].Execute(out, data)
  return string(out.Bytes())
}

謝謝!

這將使您非常接近:

SET {{range $key, $value := $.values}}{{$.bat}}.{{$key}}={{$value}} {{end}}

渲染為:

SET obj.bar=2 obj.baz=7 obj.foo=1

不幸的是,由於range操作如何在地圖上迭代(沒有數字索引),我認為沒有簡單的方法可以在值之間添加逗號。 也就是說, template包本應易於擴展,因此您可以在模板中使用較少的邏輯,而在Go本身中使用更多的邏輯,因此在Go中編寫輔助函數並將其提供給模板很容易。

如果您願意再加倍努力,那么模板將變得更加簡單,而且效率更高。 該函數可以如下所示:

func commaJoin(prefix string, m map[string]interface{}) string {
    var buf bytes.Buffer
    first := true
    for k, v := range m {
        if !first {
            buf.WriteString(", ")
        }
        first = false
        buf.WriteString(prefix)
        buf.WriteByte('.')
        buf.WriteString(k)
        buf.WriteByte('=')
        buf.WriteString(fmt.Sprint(v))
    }
    return buf.String()
}

您的模板如下所示:

SET {{$.values | commaJoin $.bat}}

這是使用此邏輯的一個有效示例:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM