英文:
How does the go 'Template.Execute' read its prameter's fields of anonymous strcuture?
问题
在使用Go编码时,使用html.template包,会调用template.Execute方法。
我有一个问题,它如何读取参数中匿名结构体的字段。
我阅读了源代码,但是不太明白。我没有主意。
在上述代码中,Template结构体定义了一个text字段,类型为*template.Template。
escape方法用于转义所有关联的模板。在执行模板转义之前,会先对nameSpace进行加锁,然后在函数结束时解锁。如果escapeErr为nil,则表示转义成功;如果Tree为nil,则表示模板不完整或为空;否则,会调用escapeTemplate函数对模板进行转义。
Execute方法用于将解析后的模板应用于指定的数据对象,并将输出写入wr。如果执行模板或写入输出时发生错误,执行将停止,但部分结果可能已经写入输出写入器。模板可以安全地并行执行。
根据GoDoc的示例,可以像这样使用Execute方法:
data := struct {
Title string
Items []string
}{
Title: "My another page",
Items: []string{},
}
err = t.Execute(os.Stdout, data)
英文:
In coding with Go, with html.template package, template.Execute is called.<br>
I have a question, how could it read the field of anonymous structure of its parameter.<br>
I read the source code, but it doesn't make sense. I don't have an idea.
> /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 demonstrates its usage, calling Execute with its interface{} paramter like this;
data := struct {
Title string
Items []string
}{
Title: "My another page",
Items: []string{},
}
err = t.Execute(os.Stdout, data)
答案1
得分: 1
如果你看一下Execute
函数的return
语句,它调用了text/template
包中的t.text.Execute
函数:
func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
defer errRecover(&err)
value := reflect.ValueOf(data)
state := &state{
tmpl: t,
wr: wr,
vars: []variable{{"$", value}},
}
if t.Tree == nil || t.Root == nil {
state.errorf("%q is an incomplete or empty template%s", t.Name(), t.DefinedTemplates())
}
state.walk(value, t.Root)
return
}
因此,它将使用reflect
包将变量解析到模板中。
这里有一个简单的示例来说明正在发生的事情:http://play.golang.org/p/ih1Ei33NsO
英文:
If you look at the return
of Execute
it calls t.text.Execute
which is calling this function from the text/template
package:
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 }
So it will use the reflect
package to parse the variables into the template.
Here's a little example of whats happening: http://play.golang.org/p/ih1Ei33NsO
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论