Go 语言的Template Package
理解template package之前,最好能快速看一下Go的一些数据结构,比如struct,array 和slice,这些数据结构在template 里面会被经常用到。 Structstruct是一个包含多个field的集合,跟C语言的结构体非常类似,可以用关键字type以及struct来定义一个struct。例如: type My_Struct_Name struct { X int Y string }
注意上面的定义的struct在当前这个package外面也是可见的,因为它的名字是以大写字母开头的。变量X和Y同样也是包外面可见的,因为它们都是大写字母开头的。可以通过.+field的名字来访问Struct里面定义的fields,比如: msn := My_Struct_Name{1,"talim"}
msn.X = 4
若通过变量名可以以任何顺序初始化这个Struct,如下: msn2 := My_Struct_Name{Y: “Talim”,X: 15}
ArrayGo语言的数组是一个包含指定数量元素的数列。 var arr [5]int
我们可以通过数组的下标来给一个元素赋值,语法是“array[index] = value”,也可以通过下标来取值。 arr2 := [5]int{1,2,3,4,5}
Sliceslice是数组的一个segment(片段), 跟数组一样,slice可以通过下标来存取,同时也有长度。跟数组不一样的是,slice的长度是可变的。下面就是一个slice的一个例子: var x []int
这个跟数组唯一不一样的就是没有在[]之间给定长度。上面就创建一个长度为0的x变量。 x := make([]int, 5)
这样就创建一个slice,它会跟一个长度为5的数组关联起来。Slices总是跟数组相关联的,它必须小于数组的长度。 text/template用法: import “text/template”
很多服务器端的语言都提供一种机制来定义一些静态的页面,然后往里面插入动态生成的组件,比如插入一个列表。典型的例子JSP/PHP里面的脚本。GO在template这个package也提供了类似的相关的脚本语言。 这个包以文本作为输入,基于对对象值的解释,把原来的输入文本转换成其它的不一样的文本。 为了生成HTML格式的文本,我们可以很快去学习关于”html/template”的package,它提供了跟text/template相同的接口,但可以自动使输出的HTML免于某些攻击。 template会作用在一个Go object上。Go object里面的field可以被插入到template,你也可以挖掘这个object来得到它所有的field,等等。可以用”.“来代表当前这个object, 因此如果想把这个object的值作为String插入到template,你可以这样用”{{.}}“。package默认会使用”fmt”这个package来生成字符串作为插入到template的值。 如果只是想把当前object的一个field的值插入到template,你可以通过在这个field的名字前面加一个前缀 “.”。 假设我们定义这样一个类型的对象: type Student struct { Name string }
然后你就可以通过下面的方式插入Name的值: The name is {{.Name}}.
所以template是一种将通用文本(不会变化的)跟特定文本作merge的方法,例如tempate可以保留里面通用的文本,然后根据需要替换一些特定的文本。 这种定义的语法就是把template的声明用“define”和“end” action包起来。 define这个action后面跟着一个字符串来指定template的名字 `{{define "T1"}}ONE{{end}} {{define "T2"}}TWO{{end}} {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}} {{template "T3"}}`
这里定义了两个template,T1和T2,第三个T3执行时会调用了其它两个template。最后调用T3。如果运行T3这个template,它会输出下面的文本: ONE TWO
在Go语言中,我们用template这个package以及它的”Parse”, “ParseFile”, “Execute”之类的方法来从字符串或者文件中加载一个template,然后做上面提到的文本的转换和merge。 需要merge的内容通常在一个自定义的类型里面,这个类型包含一些可以被外面的包访问的field,例如template用到的一些定义在struct这个类型里面的filed就需要以大写字母开头。 让我们看一个简单的例子。 创建下面一个目录并且切换到这个目录: $ mkdir $GOPATH/src/github.com/SatishTalim/texttmpl
$ cd $GOPATH/src/github.com/SatishTalim/texttmpl
在这个目录下面写个名字叫”stud_struct.go”的程序,如下: package main
import (
"log"
"os"
"text/template"
)
type Student struct {
//exported field since it begins
//with a capital letter
Name string
}
func main() {
//define an instance
s := Student{"Satish"}
//create a new template with some name
tmpl := template.New("test")
//parse some content and generate a template
tmpl,err := tmpl.Parse("Hello {{.Name}}!")
if err != nil {
log.Fatal("Parse: ",err)
return
}
//merge template 'tmpl' with content of 's'
err1 := tmpl.Execute(os.Stdout,s)
if err1 != nil {
log.Fatal("Execute: ",err1)
return
}
}
你可以敲如下的命令来执行这个程序: $ go run stud_struct.go
输出结果: Hello Satish!
注意:
让我们看另外一个例子。 创建下面一个目录并且切换到这个目录: $ mkdir $GOPATH/src/github.com/SatishTalim/person
$ cd $GOPATH/src/github.com/SatishTalim/person
在这个目录下写一个”person.go”的程序: package main
import (
"log"
"os"
"text/template"
)
type Person struct {
Name string
Emails []string
}
const tmpl = `The name is {{.Name}}.
{{range .Emails}}
His email id is {{.}}
{{end}}
`
func main() {
person := Person{
Name: "Satish",Emails: []string{"satish@rubylearning.org","satishtalim@gmail.com"},}
t := template.New("Person template")
t,err := t.Parse(tmpl)
if err != nil {
log.Fatal("Parse: ",err)
return
}
err = t.Execute(os.Stdout,person)
if err != nil {
log.Fatal("Execute: ",err)
return
}
}
敲入如下命令来运行这个程序: $ go run person.go
输出结果: The name is Satish.
His email id is satish@rubylearning.org
His email id is satishtalim@gmail.com
Go的template package在文本转换时非常有用,特别是当这个转换需要插入对象的值时。它虽没有正则表达式那么强大,但却更快并且很多情况下比正则表达式好用。 html/templateUsage: import “html/template”
“html/template”这个包实现了data-driven template,用来生成HTML输出,比直接的代码注入更安全。它提供了跟”text/template”一样的接口,当输出的格式是HTML是应该用”html/template”这个package,而不是”text/template”。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |