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

标签 go go-templates

有没有一种方法可以通过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
我知道如何为 map 执行此操作,我只会使用索引功能。但这不适用于结构,并且我没有灵活性来更改作为上下文传递的基础类型。
有任何想法吗?

最佳答案

即使在常规的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)
    }
}

go playground上看到它

关于go - 通过go模板中的字段名称动态访问结构值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63725375/

相关文章:

go - 如何在golang中查找mp3文件的长度?

go - 在 Go HTML 模板中创建结构映射键的语法

json - 使用 GO 从文件中解码 JSON 内容并使用 GO 模板包生成 .go 文件

go - 如何修剪 Go 模板中的空行?

Go嵌套模板路径作为变量

javascript - GoLang 解析 time.Now() 时区?

json - 如何将 JSON 转换为关联/索引数组

unit-testing - 如何为一小时后函数返回时间编写单元测试

mysql - 无效的内存地址或 nil 指针取消引用 golang 数据库

javascript - 在 Javascript 中引用 Go 数组