Go库text与template包使用示例详解

目录
  • 场景
  • text/template 包
    • 基本用法
    • 模板语法
      • 空白字符
      • 常用 Action
      • 函数
  • 总结

场景

现在的项目,基本都是前后端分离,后端只要提供Json等格式的数据就行。在这个背景下,模板渲染这个功能备受冷落,很少会在项目中用到。

虽然在 http 服务中,模板解析不常用,但日常开发中,巧妙利用模板生成代码,能使我们开发事半功倍。比如:

  • 使用模板初始化项目。比如我们每次新建一个 http 服务,可能都需要 promethue 监控、日志等模块。每次都实现一遍不现实,(或者 copy 别的项目),我们可以写好模板,支持自定义项目名,初始化新项目。
  • 生成代码。比如之前文章提到的 mockery,就是解析 interface 的语法树,利用模板生成 Mock 对象。

text/template 包

基本用法

text/template提供的接口和html/template包一样,只不过后者会为 html 格式的输出做转义,避免攻击。

text/template 用法很简单:

func main() {
	// 要注入的变量
	type Inventory struct {
		Material string
		Count    uint
	}
	sweaters := Inventory{"wool", 17}
	// 模板内容, {{.xxx}} 格式的都会被注入的变量替换
	text := `{{.Count}} items are made of {{.Material}}`
	TestTemplate(text, sweaters)
}
func TestTemplate(text string, data interface{}) {
	// 初始化,解析
	tmpl, err := template.New("test").Parse(text)
	if err != nil {
		panic(err)
	}
	// 输出到 os.Stdout
	err = tmpl.Execute(os.Stdout, data)
	if err != nil {
		panic(err)
	}
}

结果输出如下:

17 items are made of wool

其中,Execute的声明为:

// 第一个参数是输出的接口,第二个参数是要注入的数据
func (t *Template) Execute(wr io.Writer, data interface{}) error

第二个参数 data 是 interface{},类型不限,可以是:

  • 结构体,属性在模板中用 {{.Field}} 表示。
  • map,value 在模板中用 {{.Key}} 表示。
  • 其他简单类型(int、string等),在模板中用{{.}}表示。
	// data 为 map
	m := map[string]interface{}{"Material": "wool", "Count": 17}
	TestTemplate(`{{.Count}} items are made of {{.Material}}`, m) // 输出:17 items are made of wool
	// data 为 int,{{.}} 代表注入的变量
	TestTemplate(`{{.}} items`, 17) // 输出:17 items

另外,我们也可以使用 template.Must 来检测返回的 error, 如果 error 不为 nil 则 panic。也就是说下面的代码:

tmpl, err := template.New("test").Parse(text)
if err != nil {
  panic(err)
}

等价于:

tmpl := template.Must(template.New("test").Parse(txt))

我们重点介绍一下,Parse的参数(代码中的text变量),也就是模板的内容。

模板语法

模板里{{xxx}}格式称之为 Action,默认以{{}}作为分界符,表示模板的流程控制、或者变量。

空白字符

如果 Action 以 {{- 开头,会把 action 左边的空白字符删除,这里的空白字符包括空格、换行、tab等。同理,-}}会把右边的空白字符删除。如:

	d := struct{ Name string }{"Neil"}
	TestTemplate(`name = {{.Name}} ;`, d) // 输出:name = Neil ;
	// 删除掉 .Name 左边的空格
	TestTemplate(`name = {{- .Name}} ;`, d) // 输出:name =Neil ;
	// 删除掉 .Name 右边的空格
	TestTemplate(`name = {{.Name -}} ;`, d) // 输出:name = Neil;
	// 删除掉 .Name 两边的空格
	TestTemplate(`name = {{- .Name -}} ;`, d) // 输出:name =Neil;

常用 Action

备注,格式为 {{/*xxxx*/}},注意备注的内容是可以换行的。

text := `{{/*this is a comment*/}} name : {{.}} `
TestTemplate(text, "Neil")
// 输出:
//  name : Neil

遍历,可以使用 range 关键字。遍历的变量只能是 slice、array、map 或者 channel。

下面代码中的 {{.}} 代表 .MapContent 的元素。

d1 := struct{ MapContent []string }{MapContent: []string{"neil", "garmen", "ray"}}
text = "{{range .MapContent}}{{.}} {{end}}"
TestTemplate(text, d1)
// 输出:
// neil garmen ray

注意,这时候的.不是代表d1变量,如果希望在 range 块里面使用d1, 需要使用 {{$.}}

另外也可以使用自定义变量来遍历:

text = "{{range $i,$v := .MapContent}}{{$i}}=>{{$v}} {{end}}"
TestTemplate(text, d1)
// 输出
// 0=>neil 1=>garmen 2=>ray

if-else,变量为零值,或者空 slice、array、map,就相当于是 false。

text = `{{if .Name}}emtpy{{else}}not empty{{end}}`
d = struct{ Name string }{"Neil"}
TestTemplate(text, d) // 输出: empty

if 还可以配合 and、or、not 使用:

// .condition1 && .condition2
if and .condition1 .condition2
// .condition1 ||  .condition2
if or .condition1 .condition2
// !.condition
if not .condition

with-else, 和if基本一样。区别是,with 作用域的 {{.}} 代表 with 参数,而不是全局的 {{.}}.

text = "{{with .Name}}{{.}}{{else}}empty{{end}}"
d = struct{ Name string }{"Neil"}
TestTemplate(text, d) // 输出: Neil

自定义模板,使用 define 定义,template 引用。

text = `{{define "T1"}}ONE{{end}}
{{define "T2"}}TWO{{end}}
{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
{{template "T3"}}`
TestTemplate(text, nil)
// 输出: ONE TWO

函数

模板提供了一些函数,如上文的andornot。比如下文的 index 函数,打印 MapContent 的 index 为 1 的元素。

text = `{{index .MapContent 1}}`
d1 = struct{ MapContent []string }{MapContent: []string{"neil", "garmen", "ray"}}
TestTemplate(text, d1)
// 输出:garmen

另外,函数还能以管道的方式,一个函数的结果,作为另一个参数的输入,如 {{func1 args | func2 }}。还有可以使用自定义函数,详情可以查看官方文档:pkg.go.dev/text/templa…

总结

text/template 功能挺多,本文只是大致介绍一下,详情还得移步官网

以上就是Go库text与template包使用示例详解的详细内容,更多关于Go库text template包的资料请关注我们其它相关文章!

(0)

相关推荐

  • go语言context包功能及操作使用详解

    目录 Context包到底是干嘛用的? context原理 什么时候应该使用 Context? 如何创建 Context? 主协程通知有子协程,子协程又有多个子协程 context核心接口 emptyCtx结构体 Backgroud TODO valueCtx结构体 WithValue向context添加值 Value向context取值 示例 WithCancel可取消的context cancelCtx结构体 WithDeadline-超时取消context WithTimeout-超时取消

  • 从Context到go设计理念轻松上手教程

    目录 引言 概览 空的 cancelCtx与timerCtx.valueCtx 取消 计时器 值 使用Context的几个原则 引言 context包比较小,是阅读源码比较理想的一个入手,并且里面也涵盖了许多go设计理念可以学习.go的Context作为go并发方式的一种,无论是在源码net/http中,开源框架例如gin中,还是内部框架trpc-go中都是一个比较重要的存在,而整个 context 的实现也就不到600行,所以也想借着这次机会来学习学习,本文基于go 1.18.4. 话不多说,

  • Golang template 包基本原理分析

    目录 template 概述 解析流程 Parse阶段 Execute阶段 小结 template 概述 最近在做脚手架相关的内容, 研究了一下 Go 的 text/template 包, 接下来跟大家分享下 template 的基本原理. 在 Golang 的标准库中, 有两个和 template 有关的包, 一个是 html/template, 另外一个是 text/template, 这两个包的主要区别是 html 版本加入了很多对 js字符串 和 html标签 的处理, 下面我们主要用

  • Go模板template用法详解

    本文只介绍template的语法和用法,关于template包的函数.方法.template的结构和原理,见:深入解析Go template模板使用详解. 入门示例 以下为test.html文件的内容,里面使用了一个template语法{{.}}. <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-

  • 优雅使用GoFrame共享变量Context示例详解

    目录 前言摘要 Context是什么? 为什么需要Context? Context是如何实现共享变量的? 如何使用? 一.结构定义 介绍 二.逻辑封装 三.上下文变量注入 四.上下文变量使用 方法定义 Context对象获取 自定义Key-Value 五.注意问题 总结 前言摘要 昨天和同事merge代码又遇到了很多冲突,发现之前有些方法写的参数不规范,没有传入Context,不方便进行链路追踪.他在review项目代码,基本把项目中的方法都加了Context参数. 今天就为大家介绍一下Cont

  • 深入解析Go template模板使用详解

    本文只关注Go text/template的底层结构,带上了很详细的图片以及示例帮助理解,有些地方也附带上了源码进行解释.有了本文的解释,对于Go template的语法以及html/template的用法,一切都很简单. 关于template的语法以及具体使用方法,见:Go template用法详解 入门示例 package main import ( "html/template" "os" ) type Person struct { Name string

  • Go库text与template包使用示例详解

    目录 场景 text/template 包 基本用法 模板语法 空白字符 常用 Action 函数 总结 场景 现在的项目,基本都是前后端分离,后端只要提供Json等格式的数据就行.在这个背景下,模板渲染这个功能备受冷落,很少会在项目中用到. 虽然在 http 服务中,模板解析不常用,但日常开发中,巧妙利用模板生成代码,能使我们开发事半功倍.比如: 使用模板初始化项目.比如我们每次新建一个 http 服务,可能都需要 promethue 监控.日志等模块.每次都实现一遍不现实,(或者 copy

  • PaddleOCR 识别表情包文字示例详解

    目录 引言 安装 PaddleOCR 本地处理 在 flask 中处理 引言 最近在做个表情包的小程序,涉及到表情包搜索功能.我们上传表情包的时候,只有一张图,怎么搜索?这个时候我们想到就是将表情包的文字提取出来,作为搜索的内容.那么这就需要用到 ocr 技术了. 经过几个 ocr 的库的使用,小编强烈推荐使用 PaddleOCR,一款文本识别效果不输于商用的Python库! 对于 PaddleOCR 本文不会过多介绍,可自行搜索.重点是如何使用 PaddleOCR 解决我的问题. 安装 Pad

  • 支持cjs及esm的npm包实现示例详解

    目录 正文 tsc cjs esm package.json rollup rollup.config.js package.json webpack webpack.config.js package.json esbuild 正文 模块化是一个老生常谈的问题了,打包工具层出不穷. 那么,如何利用这些打包工具去打出既支持cjs,又支持esm的npm包呢. 这篇文章不涉及概念,是一些打包实测. demo repo: github.com/FrankKai/np… 可以clone下来,本地构建测试

  • Python程序包的构建和发布过程示例详解

    关于我 编程界的一名小程序猿,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. 联系:hylinux1024@gmail.com 当我们开发了一个开源项目时,就希望把这个项目打包然后发布到 pypi.org 上,别人就可以通过 pip install 的命令进行安装.本文的教程来自于 Python 官方文档 , 如有不正确的地方欢迎评论拍砖. 0x00 创建项目 本文使用到的项目目录为 ➜ packaging-tuto

  • go goth封装第三方认证库示例详解

    目录 简介 快速使用 更换 store 总结 简介 当前很多网站直接采用第三方认证登录,例如支付宝/微信/ Github 等.goth封装了接入第三方认证的方法,并且内置实现了很多第三方认证的实现: 图中截取的只是goth支持的一部分,完整列表可在其GitHub 首页查看. 快速使用 本文代码使用 Go Modules. 创建目录并初始化: $ mkdir goth && cd goth $ go mod init github.com/darjun/go-daily-lib/goth 安

  • Python tkinter库绘制春联和福字的示例详解

    马上要过年了,用 Python 写一副春联&福字送给大家,本文我们主要用到的 Python 库为 tkinter,下面一起来看一下具体实现. 首先,我们创建一个画布,代码实现如下: root=Tk() root.title('新年快乐') canvas=Canvas(root,width=500,height=460,bg='lightsalmon') 看一下效果: 我们接着写上联,主要代码实现如下: for i in range(0,451): canvas.create_rectangle(

  • R语言UpSet包实现集合可视化示例详解

    目录 前言 一.R包及数据 二.upset()函数 1)基本参数 2)queries参数 3)attribute.plots参数 3.1 添加柱形图和散点图 3.2 添加箱线图 3.3 添加密度曲线图 前言 介绍一个R包UpSetR,专门用来集合可视化,当多集合的韦恩图不容易看的时候,就是它大展身手的时候了. 一.R包及数据 #安装及加载R包 #install.packages("UpSetR") library(UpSetR) #载入数据集 data <- read.csv(&

  • Vue.extend实现组件库message组件示例详解

    目录 概述 Vue.extend message 组件配置对象(就是.vue文件) message 生成组件的函数 使用方法 效果图 总结 概述 当我们使用组件库的时候,某些组件并不是直接放到模板当中进行使用,而是通过api的方式调用生成组件并且挂在到我们的页面中,其中最常见的就是message组件,我们在组件库中看到的多数都是api调用的方式生成.记录自己基本实现message组件. Vue.extend 在vue中,要实现通过api方式实现组件的使用,这个aip是必不可少的,因此我们先了解下

  • GScript 编写标准库示例详解

    目录 版本更新 引言 使用 Docker 编写 GScript 标准库 版本更新 最近 GScript 更新了 v0.0.11 版本,重点更新了: Docker 运行环境 新增了 byte 原始类型 新增了一些字符串标准库 Strings/StringBuilder 数组切片语法:int[] b = a[1: len(a)]; 引言 前段时间发布了 GScript 的在线 playground, 这是一个可以在线运行 GScript 脚本的网站,其本质原理是接收用户的输入源码从而在服务器上运行的

  • Python使用Crypto库实现加密解密的示例详解

    目录 一:crypto库安装 二:python使用crypto 1:crypto的加密解密组件des.py 2:crypto组件使用 知识补充 一:crypto库安装 pycrypto,pycryptodome是crypto第三方库,pycrypto已经停止更新三年了,所以不建议安装这个库:pycryptodome是pycrypto的延伸版本,用法和pycrypto 是一模一样的:所以只需要安装pycryptodome就可以了 pip install pycryptodome 二:python使

随机推荐