go 'Template.Execute' 是如何读取其匿名结构的参数字段的?
How does the go 'Template.Execute' read its prameter's fields of anonymous strcuture?
在使用 Go 编码时,使用 html.template 包,调用 template.Execute。
我有一个问题,它如何读取其参数的匿名结构字段。
看了源码,没看懂。我不知道。
/usr/local/go/src/html/template/tempalte.go L.78
type Template struct {
...
text *template.Template
...
}
// escape escapes all associated templates.
func (t *Template) escape() error {
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
if t.escapeErr == nil {
if t.Tree == nil {
return fmt.Errorf("template: %q is an incomplete or empty template%s", t.Name(), t.text.DefinedTemplates())
}
if err := escapeTemplate(t, t.text.Root, t.Name()); err != nil {
return err
}
} else if t.escapeErr != escapeOK {
return t.escapeErr
}
return nil
}
// Execute applies a parsed template to the specified data object,
// writing the output to wr.
// If an error occurs executing the template or writing its output,
// execution stops, but partial results may already have been written to
// the output writer.
// A template may be executed safely in parallel.
func (t *Template) Execute(wr io.Writer, data interface{}) error {
if err := t.escape(); err != nil {
return err
}
return t.text.Execute(wr, data)
}
GoDoc 演示了它的用法,调用 Execute 的接口{}参数是这样的;
data := struct {
Title string
Items []string
}{
Title: "My another page",
Items: []string{},
}
err = t.Execute(os.Stdout, data)
如果您查看 Execute
的 return
,它会调用 t.text.Execute
,它会从 text/template
包中调用此函数:
132 func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
133 defer errRecover(&err)
134 value := reflect.ValueOf(data)
135 state := &state{
136 tmpl: t,
137 wr: wr,
138 vars: []variable{{"$", value}},
139 }
140 if t.Tree == nil || t.Root == nil {
141 state.errorf("%q is an incomplete or empty template%s", t.Name(), t.DefinedTemplates())
142 }
143 state.walk(value, t.Root)
144 return
145 }
因此它将使用 reflect
包将变量解析到模板中。
这里有一个小例子:http://play.golang.org/p/ih1Ei33NsO
在使用 Go 编码时,使用 html.template 包,调用 template.Execute。
我有一个问题,它如何读取其参数的匿名结构字段。
看了源码,没看懂。我不知道。
/usr/local/go/src/html/template/tempalte.go L.78
type Template struct {
...
text *template.Template
...
}
// escape escapes all associated templates.
func (t *Template) escape() error {
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
if t.escapeErr == nil {
if t.Tree == nil {
return fmt.Errorf("template: %q is an incomplete or empty template%s", t.Name(), t.text.DefinedTemplates())
}
if err := escapeTemplate(t, t.text.Root, t.Name()); err != nil {
return err
}
} else if t.escapeErr != escapeOK {
return t.escapeErr
}
return nil
}
// Execute applies a parsed template to the specified data object,
// writing the output to wr.
// If an error occurs executing the template or writing its output,
// execution stops, but partial results may already have been written to
// the output writer.
// A template may be executed safely in parallel.
func (t *Template) Execute(wr io.Writer, data interface{}) error {
if err := t.escape(); err != nil {
return err
}
return t.text.Execute(wr, data)
}
GoDoc 演示了它的用法,调用 Execute 的接口{}参数是这样的;
data := struct {
Title string
Items []string
}{
Title: "My another page",
Items: []string{},
}
err = t.Execute(os.Stdout, data)
如果您查看 Execute
的 return
,它会调用 t.text.Execute
,它会从 text/template
包中调用此函数:
132 func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
133 defer errRecover(&err)
134 value := reflect.ValueOf(data)
135 state := &state{
136 tmpl: t,
137 wr: wr,
138 vars: []variable{{"$", value}},
139 }
140 if t.Tree == nil || t.Root == nil {
141 state.errorf("%q is an incomplete or empty template%s", t.Name(), t.DefinedTemplates())
142 }
143 state.walk(value, t.Root)
144 return
145 }
因此它将使用 reflect
包将变量解析到模板中。
这里有一个小例子:http://play.golang.org/p/ih1Ei33NsO