【问题标题】:Iterate through map in Go text template遍历 Go 文本模板中的地图
【发布时间】:2013-09-10 21:01:02
【问题描述】:

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

谢谢!

【问题讨论】:

    标签: go go-templates


    【解决方案1】:

    这会让你非常接近:

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

    这是一个具有此逻辑的工作示例:

    【讨论】:

    • 啊,这就是你调用函数的正确方式。完美运行,谢谢!
    • @Gustavo,在这里使用管道而不是简单的函数调用有什么好处?我建议改用'SET {{commaJoin $.bat $.values}}',恕我直言,它更容易理解。
    • 我倾向于将格式化逻辑编写为管道,因为它似乎更容易发现正在格式化的内容,但这肯定是一个偏好问题。
    猜你喜欢
    • 2014-02-13
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2016-02-24
    • 2012-09-14
    • 2011-03-23
    相关资源
    最近更新 更多