遍历map列表的Golang模板遇到的问题及解决方式
出现了什么问题?
今天在使用 go template 渲染文本的时候,在运行的时候,遇到了一个问题导致渲染不成功,具体的问题是:
2021/09/10 09:47:05 template: test:2:3: executing "test" at <.Attributes>: can't evaluate field Attributes in type interface {}
具体的代码如下:
package main
import (
"log"
"os"
"strings"
"text/template"
)
type TestData struct {
Name string `json:"name"`
Attributes map[string]interface{}
}
const testTemplate = `{{ range $key, $value := .Attributes }}
{{.Name}} {{ $key }}: {{ $value }}{{- end }}`
func main() {
tmpl, err := template.New("test").Parse(strings.TrimSpace(testTemplate))
if err != nil {
log.Println(err)
return
}
data := TestData{
"hello",
map[string]interface{}{
"key": "hello",
"value": "json",
},
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
log.Println(err)
return
}
}
问题出现的原因?
模板在 range循环中会把.设置为当前 Attributes 变量, 在 Attributes 变量中没有 name 这个成员结构, 这就导致模板没有渲染成功。
解决
只要在 {{ .Name}} 中在变量前加个 $ 符号 {{ $.Name}}, $表示传递给模板执行的参数, 不是range循环值, 通过添加符号就可以成功渲染Name。
最终代码:
package main
import (
"log"
"os"
"strings"
"text/template"
)
type TestData struct {
Name string `json:"name"`
Attributes map[string]interface{}
}
const testTemplate = `{{ range $key, $value := .Attributes }}
{{ $.Name}} {{ $key }}: {{ $value }}{{- end }}`
func main() {
tmpl, err := template.New("test").Parse(strings.TrimSpace(testTemplate))
if err != nil {
log.Println(err)
return
}
data := TestData{
"hello",
map[string]interface{}{
"key": "hello",
"value": "json",
},
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
log.Println(err)
return
}
}
运行结果:
hello key: hello
hello value: json