我有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())
}
谢谢!
答案 0 :(得分:3)
这会让你非常接近:
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}}
这是一个有这个逻辑的工作示例: