go 模板详说
模板是我们常用的手段用于动态生成页面,或者用于代码生成器的编写等。比如把数据库的表映射成go
语言的struct
,这些体力活,写个代码生成器是最合适不过的了.
示例例把表转成 struct :
当然这篇帖子不是写关于代码生成器的,是详细说一下go
的Template
,对Template
的操作熟悉了后,就可以利用他实现你想要的一些功能。
渲染对象
{{.}}
来渲染对象本身,对象内部的字段可以{{.field}}
比如下面,我是用一个 map
来存储的数据,访问key: name
,并使用{{.}}
来把 map
打印出来
eg:
tmpl, err := template.New("test").Parse(`hello {{.name}}!
obj: {{.}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
"name": "world", "age": 18})
if err != nil {
panic(err)
}
输出
hello world!
obj: map[age:18 name:world]
结构体内的字段也是用{{.field}}
tmpl, err := template.New("test").Parse(`hello {{.Name}}!
obj: {{.}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
空格
在{{}}
内添加 -
可以去掉空格
-
{{- }}
去掉左边所有的空格 -
{{ -}}
去掉右边所有的空格 -
{{- -}}
去掉两边所有的空格eg:
tmpl, err := template.New("test").Parse(`hello: {{- .Name}}
age: {{.Age -}} !!!
obj:
{{- . -}} end.`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
-
hello:
后面的空格到{{- .Name}}
之间的空格会被去掉. -
{{.Age -}}
到!!!
之间的空格会被去掉 -
obj:
到{{- . -}}
到end.
之间的空格都会被去掉。
hello:li
age: 18!!!
obj:{li 18}end.
自定义变量
除了可以直接使用go
的对象,也可以直接在模板中定义变量{{ $var := }}
,变量定义后,可以在模板内其他任意地方使用:
tmpl, err := template.New("test").Parse(`{{$a := "li"}} hello {{$a}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
输出
hello li
方法
方法可以分为全局方法和结构体方法还有内置方法,内置方法也是全局方法的一种
全局方法
template.FuncMap
是一个map
里面的value
必需是方法,传入的值的参数没有限制
type FuncMap map[string]interface{}
比如:定义一个ReplaceAll
方法,替换所有的指定字符串
例子中把所有的zhang
替换成li
tmpl, err := template.New("test").Funcs(template.FuncMap{
"ReplaceAll": func(src string, old, new string) string {
return strings.ReplaceAll(src, old, new)
},
}).Parse(`func replace: {{ReplaceAll .Name "zhang" "li"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "zhang_san zhang_si", Age: 18})
if err != nil {
panic(err)
}
输出
func replace: li_san li_si
内置方法
模板有一些内置方法比如 call
printf
等,和全局方法一样,直接调用就行
tmpl, err := template.New("test").Parse(`{{printf "name: %s age: %d" .Name .Age}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
输出
name: li age: 18
行为
常用的行为有if
range
template
等
if
判断 {{if }} {{end}}
,可以用于字符串
bool
或者数值类型
当 字符串有数据
或者bool
值为true
或者数值类型
大于0
时为真
tmpl, err := template.New("test").Parse(`
name: {{.Name}}
{{- if .Name}}
string .Name true
{{else}}
string .Name false
{{end -}}
desc: {{.Desc}}
{{- if .Desc}}
string .Desc true
{{else}}
string .Desc false
{{end -}}
age: {{.Age}}
{{- if .Age}}
number .Age true
{{else}}
number .Age true false
{{end -}}
isAdmin: {{.IsAdmin}}
{{- if .Age}}
bool .IsAdmin true
{{else}}
bool .IsAdmin true false
{{end}}
`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Desc string
Age int
IsAdmin bool
}{Name: "", Desc: "xyz", Age: 18, IsAdmin: true})
if err != nil {
panic(err)
}
输出:
name:
string .Name false
desc: xyz
string .Desc true
age: 18
number .Age true
isAdmin: true
bool .IsAdmin true
range
range
用于遍例数组,和go
的 range
一样,可以直接得到每个变量,或者得到 index
和value
tmpl, err := template.New("test").Parse(`
{{range .val}} {{.}} {{end}}
{{range $idx, $value := .val}} id: {{$idx}}: {{$value}} {{end}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
"val": []string{"a", "b", "c", "d"}})
if err != nil {
panic(err)
}
输出
a b c d
id: 0: a id: 1: b id: 2: c id: 3: d
内嵌template
除了可以在自定义对象还可以自定义内嵌的模板{{define "name"}}
,也可以传参数
tmpl, err := template.New("test").Parse(`
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
在调用时{{template "content" "zhang san"}}
传递了参数 zhang san
输出:
content: hello zhang san
注释
模板的注释: {{/* comment */}}
tmpl, err := template.New("test").Parse(`
{{/* 注释 */}}
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
AI+数据科学:六种方式改变体育行业
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 随着科技的发展,人工智能与数据科学已经在体育领域发挥越来越重要的作用。世界上鲜有事物无法量化,而能够量化的一切,都可以使用数据分析加人工智能的组合进行精确预测。拿体育领域来说,其中的可量化元素就非常丰富,正合适人工智能在其中大显身手。另外需要澄清的一点是,人工智能在体育领域的应用绝不仅限于提高运动员的赛场表现。毕竟现代体育运动的涵盖范围已经非常广泛,绝不仅仅体现在运动员群体身上。 下面,我们具体聊聊AI与数据科学影响体育世界的六种具体方式。 1.发现人才、招募人才 无论是棒球、橄榄球还是其他体育项目,运动队伍都在越来越多地使用运动员个人表现数据来衡量他们是否拥有良好的身体条件与发展潜力。但在筛选下一位体育巨星的过程中,单凭公开的统计数据(例如奔跑速度、射门精度或者传球水平)是远远不够的,我们需要考虑更为复杂的多因素指标。 在这方面,人类天然的局限性导致我们无法准确记录并评估这些指标。随着大数据与人工智能全面入驻体育领域,对此类成功指标的管理、记录与衡量过程也变得愈发便捷且可靠。计算机视觉...
-
下一篇
JVM内存分析,以及一步步详解Java程序是如何运行的?
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! VM也就是Java虚拟机,它的内存结构这块知识点。 你说它重要吧,编写代码基本用不到它; 你说它不重要吧,程序员想要进阶又必须对底层有一定的了解。 最终还是决定更加深入地学习下JVM,同时也用自己的理解详细地说明Java程序是如何运行的。 当然本人目前的能力有限,只能说尽己之能学的越多越好。 一、Java程序开发三步骤 编写、编译和运行,图解如下: ①编写阶段 后缀名为.Java的文件,也就是所谓的源码。 但是Java虚拟机它并不认识.Java文件,Java虚拟机和Java语言其实并没有必然的联系。 其实我挺想吐槽的,你们长的这么像,竟然不认识? 那为何不认识呢? 按照我个人的理解,我们常说的代码、Java语言,其实本质上还是人类定义的一门语言,主要由英文组成,Java虚拟机 本身并不认识它。 所以需要将其编译成Java虚拟机 认识的语言,即.class文件。 ②编译阶段 后缀名为.class的文件,也就是所谓的字节码文件。 字节码文件,就可以理解成我们写代码一个类(接口、枚举、注释)里...
相关文章
文章评论
共有0条评论来说两句吧...