Go 模板——结构与数据控制
http://golang.org/pkg/text/template/ 与 http://golang.org/pkg/html/template/ 是Go官方的关于 *template*包的文档,——html子包提供了一些附加的安装相关的功能,比如防止代码注入的功能经常在我们的网络编程中被使用。
管道(Pipeline)
Unix 用户肯定是明白什么是 Piping 数据,很多程序都提供字符输出——一个字条流,比如你在终端中键入 ls 命令,你将得到一个包含所有当前目录文件名称的列表,它可以被翻译为:“获取当前目录中所有文件名称的列表,然后通过管道将其传送到标准输出,而当前标准输出为命令行终端的屏幕”。
在Unix命令行终端中,管道“*|*”就可以将你一个命令的输入传送给另一个命令,比如:
cox@Cox:~$ ls | grep "a"
access_log
examples.desktop
goworkspace
VirtualBox VMs
workspace上面的命令 ls 首先获取当前目录下所有文件的列表,然后再通过管道传递给 grep 命令,grep 从里面搜索包含字符“a”的条目,然后再将过滤后的结果通过管道传递给标准输出,标准输出打印出所有结果,如果你还想再过滤,还可以这样:
cox@Cox:~$ ls | grep "a" | grep "V"
VirtualBox VMs在Go中,我们也可以将任何一个像上面这样的字符流称之为管道,它们同样可以通过管道传送给其它命令,在下面的示例中,处于 {{ }} 中间的字符串与外面的字符串是不一样的——这些静态文本被无修改的复制到外面。
package main
import (
"text/template"
"os"
)
func main() {
t := template.New("Template Test")
t = template.Must(t.Parse("This is just static text. n{{"This is pipeline data - because it is evaluated within the double braces."}} {{ `So is this, but within reverse quotes.`}}n"))
t.Execute(os.Stdout, nil)
}输出为:
This is just static text.
This is pipeline data - because it is evaluated within the double braces. So is this, but within reverse quotes.模板中的 if-else-end
在模板中使用 if-else 控制结构与在普通代码中使用差不多,在Go模板中,如果传送数据到if的管道为空,则等同为 false:
package main
import (
"os"
"text/template"
)
func main() {
tEmpty := template.New("template test")
tEmpty = template.Must(tEmpty.Parse("Empty pipeline if demo: {{if ``}} Will not print. {{ end}}n"))
tEmpty.Execute(os.Stdout, nil)
tWithValue := template.New("template test")
tWithValue = template.Must(tWithValue.Parse("Non empty pipline if demo: {{if `anything`}} Print If Part.{{ end}}n"))
tWithValue.Execute(os.Stdout, nil)
tIfElse := template.New("template test")
tIfElse = template.Must(tIfElse.Parse("If-else demo:{{if `anything`}} Print IF Part. {{ else }} Else part. {{end}}n"))
tIfElse.Execute(os.Stdout, nil)
}输出为:
Empty pipeline if demo:
Non empty pipline if demo: Print If Part.
If-else demo: Print IF Part.点(*.*)
在Go模板中,点(.)被用来引用当前的管道,你可以想像成为这个点是 Java 中的 this 或者我们在Python中最常使用的 *self*,你可以使用 *{{.}}*引用到它的值。
with-end 结构
with 声明用来设置 点(.) 在管道中的数据:
package main
import (
"os"
"text/template"
)
func main() {
t, _ := template.New("test").Parse("{{with `hello`}}{{.}}{{end}}!n")
t.Execute(os.Stdout, nil)
t1, _ := template.New("test").Parse("{{with `hello`}}{{.}} {{with `Mary`}}{{.}}{{end}}{{end}}!n") //when nested, the dot takes the value according to closest scope.
t1.Execute(os.Stdout, nil)
}输出为:
hello!
hello Mary!模板变量
你可以在模板管道中使用*$*前缀创建本地变量,变量名称必须为英文字母、数字以及下划线:
package main
import (
"os"
"text/template"
)
func main() {
t := template.Must(template.New("name").Parse("{{with $3 := `hello`}}{{$3}}{{end}}!n"))
t.Execute(os.Stdout, nil)
t1 := template.Must(template.New("name1").Parse("{{with $x3 := `hola`}}{{$x3}}{{end}}!n"))
t1.Execute(os.Stdout, nil)
t2 := template.Must(template.New("name2").Parse("{{with $x_1 := `hey`}}{{$x_1}} {{.}} {{$x_1}}{{end}}!n"))
t2.Execute(os.Stdout, nil)
}被重新定义的函数
Go模板同样还提供了一些被重新定义了的函数,比如下面这个示例的 printf 就与 fmt.Sprintf 类似:
package main
import (
"os"
"text/template"
)
func main() {
t := template.New("test")
t = template.Must(t.Parse("{{with $x := `hello`}}{{printf `%s %s` $x `Mary`}}{{end}}!n"))
t.Execute(os.Stdout, nil)
}输出为:
hello Mary!
评论已关闭