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)
}
go 模板详说的更多相关文章
- C++模板详解
参考:C++ 模板详解(一) 模板:对类型进行参数化的工具:通常有两种形式: 函数模板:仅参数类型不同: 类模板: 仅数据成员和成员函数类型不同. 目的:让程序员编写与类型无关的代码. 注意:模板 ...
- 25.C++- 泛型编程之函数模板(详解)
本章学习: 1)初探函数模板 2)深入理解函数模板 3)多参函数模板 4)重载函数和函数模板 当我们想写个Swap()交换函数时,通常这样写: void Swap(int& a, int&am ...
- 26.C++- 泛型编程之类模板(详解)
在上章25.C++- 泛型编程之函数模板(详解) 学习了后,本章继续来学习类模板 类模板介绍 和函数模板一样,将泛型思想应用于类. 编译器对类模板处理方式和函数模板相同,都是进行2次编译 类模板通 ...
- c3p0-config.xml模板详解
c3p0-config.xml模板详解 <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.De ...
- C++ 类模板详解(一):概念和基本使用方式
与函数模板类似地(C++函数模板详解(一):概念和特性) ,类也可以被一种或多种类型参数化.例如,容器类就是一个具有这种特性的典型例子,它通常被用于管理某种特定类型的元素.只要使用类模板,我们就可以实 ...
- C++模板详解(三):参数化声明详解
在前两节中(C++模板详解(一).C++模板详解(二)),我们了解了函数模板和类模板的基本概念和使用方法.在这篇博文里,我们主要来详细地阐述一下"模板的参数声明"这个话题,并且也谈 ...
- 【转】 C++模板详解
C++模板 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数.返回值取得任意类型. 模板是一种对类型进行参数化的工具: 通常有 ...
- Percona监控MySQL模板详解
InnoDB Adaptive Hash Index 显示了"自适应哈希索引"的使用情况,哈希索引只能用来搜索等值的查询. # Hash table size 17700827, ...
- 28.C++- 单例类模板(详解)
单例类 描述 指在整个系统生命期中,一个类最多只能有一个实例(instance)存在,使得该实例的唯一性(实例是指一个对象指针) , 比如:统计在线人数 在单例类里,又分为了懒汉式和饿汉式,它们的区 ...
- C++模板详解——使用篇
假如我们需要取得两个变量中较大的变量,或许,我们可以通过重载的方式实现,如下. int max(int fir,int sec); float max(float fir,float sec); do ...
随机推荐
- node实现防盗链
什么是防盗链 盗链,顾名思义就是盗窃链接,就是在他人未经允许的情况下,去使用他人站点的任何图片,视频,内容等资源,来借此提升已用的站点的活跃度,严重损坏了别人的利益.那么防盗链就是采用一些办法阻止自己 ...
- 解决click与hover(mouseover)的冲突问题
主要应用到一个知识点:$(selector).data('name','value'); <!DOCTYPE HTML> <html> <head> <met ...
- mysql定期任务
进来开发项目时遇到一个问题,就是每一周需要清理服务器数据库数据.现在我就来记录一下用Navicat for MySQL 来实现定时任务. 1.启动Navicat for MySQL,新建数据库连接,打 ...
- Problem D. Ice Cream Tower
题解:二分加贪心,,,二分答案,然后进行判断,判断的时候,首先给每一组配一个最大的球,然后在向每一组里面填球,注意填球的时候要按组进行,每一组先填一个,然后更新每一组内的最小值,方便下一次寻找. #i ...
- CSRF(跨站请求伪造)学习总结
前言 参考大佬的文章,附上地址 https://www.freebuf.com/articles/web/118352.html 什么是CSRF? CSRF,中文名字,跨站请求伪造,听起来是不是和XS ...
- 详解 LinkedHashMap
同学们可能在看到这个类的时候就明白了很多关于这个类的特点,那么,本人就在这里来啰嗦一下,再来介绍下这个类: (有关Map集合的基本性质,请观看本人博文-- <详解 Map集合>) Link ...
- Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题
1.创建Api项目 我用的是VS2019 Core3.1 .打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加 ...
- jQuery(*****)
参考1 参考2 1. jQuery 1. 选择器 $("") 1. 基本选择器 1. ID --> $("#d1") 2. 标签名 --> $(&q ...
- 基于 HTML5 WebGL 的污水处理厂泵站自控系统
前言 一道残阳铺水中,半江瑟瑟半江红.随着城市建设的迅速发展,每年都有大量新建管网水管通水运行.城市中有大量的排水设备,形成相应的城市排水系统,排水系统由检查井.排水泵站.污水处理厂.雨水口.排放口等 ...
- token认证和理解
认知篇:https://blog.csdn.net/FYGu18/article/details/89345490 token失效篇认知:https://segmentfault.com/q/1010 ...