在 go 模板中通过字段名动态访问结构值

有没有办法通过 go 模板中的字段名动态访问结构值?


对于此代码(https://play.golang.org/p/1B1sz0gnbAi):


package main


import (

    "fmt"

    "os"

    "text/template"

)


type Context struct {

    Key string

}


func main() {

    var context = Context{Key: "value"}


    // Success

    var text = `{{ .Key }}`


    t := template.Must(template.New("success").Parse(text))

    _ = t.Execute(os.Stdout, context)


    fmt.Println("")

    

    // Fail

    text = `{{- $key := "Key" }}{{ .$key}}`

    t = template.Must(template.New("fail").Parse(text))

    err := t.Execute(os.Stdout, context)

    if err != nil {

        fmt.Println("executing template:", err)

    }

}

我得到这个输出:


value

panic: template: fail:1: unexpected bad character U+0024 '$' in command


goroutine 1 [running]:

text/template.Must(...)

    /usr/local/go-faketime/src/text/template/helper.go:23

main.main()

    /tmp/sandbox897259471/prog.go:26 +0x46b

我知道如何为地图执行此操作,我只会使用索引函数。但这不适用于结构,并且我没有灵活性来更改作为上下文传递的基础类型。


有任何想法吗?


慕无忌1623718
浏览 132回答 1
1回答

HUH函数

即使在常规的 golang 代码中,按名称访问结构字段也需要反射,因此在模板中也不是那么容易。没有允许它的内置函数,我也不知道有任何库提供这样的功能。您可以做的是自己实现该功能。一个非常基本的实现可能如下:package mainimport (    "fmt"    "os"    "text/template"    "reflect")type Context struct {    Key string}func FieldByName(c Context, field string) string {    ref := reflect.ValueOf(c)    f := reflect.Indirect(ref).FieldByName(field)    return string(f.String())}func main() {    context := Context{Key: "value"}    text := `{{- $key := "Key" }}{{ fieldByName . $key}}`        // Custom function map    funcMap := template.FuncMap{        "fieldByName": FieldByName,    }    // Add custom functions using Funcs(funcMap)    t := template.Must(template.New("fail").Funcs(funcMap).Parse(text))        err := t.Execute(os.Stdout, context)    if err != nil {        fmt.Println("executing template:", err)    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go