下面代码希望自定义一个template函数,函数返回值TF,结果却得到了<invalid reflect.Value>错误,求解。
```
package main
import (
"fmt"
"os"
"reflect"
"text/template"
)
func getByKey(data interface{}, keys ...string) interface{} {
var rdata reflect.Value
for _, k := range keys {
rdata = reflect.ValueOf(data)
switch rdata.Kind() {
case reflect.Map:
mdata := data.(map[string]ZkNode)
data = mdata[k]
default:
data = rdata.FieldByName(k)
}
}
return data
}
type ZkNode struct {
Value interface{}
Key string
Zz interface{}
}
func main() {
data := make(map[string]ZkNode)
data["test1"] = ZkNode{
Value: "123",
Key: "test1_key",
}
data["test2"] = ZkNode{
Value: "456",
Key: "test2_key",
Zz: &ZkNode{
Value: "TF",
Key: "aaa",
},
}
tmplStr := `
begin
{{D . "test2" "Zz" "Value" }}
end
`
tmpl, err := template.New("myt").Funcs(template.FuncMap{"D": getByKey}).Parse(tmplStr)
if err != nil {
fmt.Println(err)
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
fmt.Println(err)
}
}
```
更多评论
I got it myself.
```
package main
import (
"fmt"
"os"
"reflect"
"text/template"
)
func getByKey(data interface{}, keys ...string) interface{} {
defer func() {
err := recover()
if err != nil {
fmt.Println(err)
}
}()
for _, k := range keys {
rdata := reflect.ValueOf(data)
switch rdata.Kind() {
case reflect.Map:
mdata := data.(map[string]ZkNode)
data = mdata[k]
case reflect.Ptr:
data = rdata.Elem().FieldByName(k).Interface()
default:
data = rdata.FieldByName(k).Interface()
}
}
return data
}
type ZkNode struct {
Value interface{}
Key string
Zz interface{}
}
func main() {
data := make(map[string]ZkNode)
data["test1"] = ZkNode{
Value: "123",
Key: "test1_key",
}
data["test2"] = ZkNode{
Value: "456",
Key: "test2_key",
Zz: &ZkNode{
Value: "TF",
Key: "aaa",
},
}
tmplStr := `
begin
{{D . "test2" "Zz" "Value" }}
end
`
tmpl, err := template.New("myt").Funcs(template.FuncMap{"D": getByKey}).Parse(tmplStr)
if err != nil {
fmt.Println(err)
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
fmt.Println(err)
}
}
```
#1