为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕无忌1623718 2022-06-27 15:39:48
有没有办法通过 go 模板中的字段名动态访问结构值?对于此代码(https://play.golang.org/p/1B1sz0gnbAi):package mainimport (    "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)    }}我得到这个输出:valuepanic: template: fail:1: unexpected bad character U+0024 '$' in commandgoroutine 1 [running]:text/template.Must(...)    /usr/local/go-faketime/src/text/template/helper.go:23main.main()    /tmp/sandbox897259471/prog.go:26 +0x46b我知道如何为地图执行此操作,我只会使用索引函数。但这不适用于结构,并且我没有灵活性来更改作为上下文传递的基础类型。有任何想法吗?
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

即使在常规的 golang 代码中,按名称访问结构字段也需要反射,因此在模板中也不是那么容易。没有允许它的内置函数,我也不知道有任何库提供这样的功能。您可以做的是自己实现该功能。一个非常基本的实现可能如下:


package main


import (

    "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)

    }

}



查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信