go - 在 Go 文本模板中遍历 map

标签 go go-templates

我有一个 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

即使这样做有效,逗号也会不正确。然后我尝试使用自定义函数来格式化 map ,但我无法让模板调用我的函数。以下似乎都不起作用:

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 操作如何在 map 上迭代(没有数字索引),我认为没有任何简单的方法可以在值之间添加逗号。也就是说,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}}

这是一个使用此逻辑的工作示例:

关于go - 在 Go 文本模板中遍历 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18728682/

相关文章:

kubernetes-helm - 如何在三元语句中连接变量?

templates - Golang中如何同时使用 "html/template"和 "text/template"

html - 使用go模板解析页面中显示为纯文本的HTML代码

string - 文本/模板如何确定 map 的 "default textual representation"?

json - 如何从 interface{} 转换为 struct 实例

http - 如何获取刚在Go中设置的HTTP header 的字符串值?

go - 其他语言和curl成功后,无法发送Go请求(EOF或“对等重置连接”)

go - 如何与 gorilla 复用器建立无状态连接?

go - 在 go 中按顺序将 protobuf 消息写入文件