Go template高级用法、深入详解、手册、指南、剖析 您所在的位置:网站首页 go语言模块 Go template高级用法、深入详解、手册、指南、剖析

Go template高级用法、深入详解、手册、指南、剖析

2023-10-13 23:10| 来源: 网络整理| 查看: 265

以下为test.html文件的内容,里面使用了一个template语法{{.}}。

Go Web {{ . }}

以下是test.html同目录下的一个go web程序:

package main import ( "html/template" "net/http" ) func tmpl(w http.ResponseWriter, r *http.Request) { t1, err := template.ParseFiles("test.html") if err != nil { panic(err) } t1.Execute(w, "hello world") } func main() { server := http.Server{ Addr: "127.0.0.1:8080", } http.HandleFunc("/tmpl", tmpl) server.ListenAndServe() }

前面的html文件中使用了一个template的语法{{.}},这部分是需要通过go的template引擎进行解析,然后替换成对应的内容。

在go程序中,handler函数中使用template.ParseFiles("test.html"),它会自动创建一个模板(关联到变量t1上),并解析一个或多个文本文件(不仅仅是html文件),解析之后就可以使用Execute(w,"hello world")去执行解析后的模板对象,执行过程是合并、替换的过程。例如上面的{{.}}中的.会替换成当前对象"hello world",并和其它纯字符串内容进行合并,最后写入w中,也就是发送到浏览器"hello world"。

本文不解释这些template包的函数、方法以及更底层的理论知识,本文只解释template的语法,如果觉得这些无法理解,或者看不懂官方手册,请看深入剖析Go template。

关于点"."和作用域

在写template的时候,会经常用到"."。比如{{.}}、{{len .}}、{{.Name}}、{{$x.Name}}等等。

在template中,点"."代表当前作用域的当前对象。它类似于java/c++的this关键字,类似于perl/python的self。如果了解perl,它更可以简单地理解为默认变量$_。

例如,前面示例test.html中{{.}},这个点是顶级作用域范围内的,它代表Execute(w,"hello worold")的第二个参数"hello world"。也就是说它代表这个字符串对象。

再例如,有一个Person struct。

type Person struct { Name string Age int } func main(){ p := Person{"longshuai",} tmpl, _ := template.New("test").Parse("Name: {{.Name}}, Age: {{.Age}}") _ = tmpl.Execute(os.Stdout, p) }

这里{{.Name}}和{{.Age}}中的点"."代表的是顶级作用域的对象p,所以Execute()方法执行的时候,会将{{.Name}}替换成p.Name,同理{{.Age}}替换成{{p.Age}}。

但是并非只有一个顶级作用域,range、with、if等内置action都有自己的本地作用域。它们的用法后文解释,这里仅引入它们的作用域来解释"."。

例如下面的例子,如果看不懂也没关系,只要从中理解"."即可。

package main import ( "os" "text/template" ) type Friend struct { Fname string } type Person struct { UserName string Emails []string Friends []*Friend } func main() { f1 := Friend{Fname: "xiaofang"} f2 := Friend{Fname: "wugui"} t := template.New("test") t = template.Must(t.Parse( `hello {{.UserName}}! {{ range .Emails }} an email {{ . }} {{- end }} {{ with .Friends }} {{- range . }} my friend name is {{.Fname}} {{- end }} {{ end }}`)) p := Person{UserName: "longshuai", Emails: []string{"[email protected]", "[email protected]"}, Friends: []*Friend{&f1, &f2}} t.Execute(os.Stdout, p) }

输出结果:

hello longshuai! an email [email protected] an email [email protected] my friend name is xiaofang my friend name is wugui

这里定义了一个Person结构,它有两个slice结构的字段。在Parse()方法中:

顶级作用域的{{.UserName}}、{{.Emails}}、{{.Friends}}中的点都代表Execute()的第二个参数,也就是Person对象p,它们在执行的时候会分别被替换成p.UserName、p.Emails、p.Friends。因为Emails和Friend字段都是可迭代的,在{{range .Emails}}...{{end}}这一段结构内部an email {{.}},这个"."代表的是range迭代时的每个元素对象,也就是p.Emails这个slice中的每个元素。同理,with结构内部{{range .}}的"."代表的是p.Friends,也就是各个,再此range中又有一层迭代,此内层{{.Fname}}的点代表Friend结构的实例,分别是&f1和&f2,所以{{.Fname}}代表实例对象的Fname字段。去除空白

template引擎在进行替换的时候,是完全按照文本格式进行替换的。除了需要评估和替换的地方,所有的行分隔符、空格等等空白都原样保留。所以,对于要解析的内容,不要随意缩进、随意换行。

可以在{{符号的后面加上短横线并保留一个或多个空格"- "来去除它前面的空白(包括换行符、制表符、空格等),即{{- xxxx。

在}}的前面加上一个或多个空格以及一个短横线"-"来去除它后面的空白,即xxxx -}}。

例如:

{{23}} < {{45}} -> 23 < {{23}} < {{- 45}} -> 23 23< {{23 -}} < {{- 45}} -> 23


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有