本文介绍: Go text/template 是 Go 语言标准库中的一个模板引擎用于生成文本输出。它使用类似于 HTML 的模板语言,可以数据模板结合起来,生成最终的文本输出。Go text/template一个简单易用、安全可靠、高效性能、灵活可扩展模板引擎,适用于生成各种类型的文本输出。在使用模板时,应该遵循最佳实践,注意模板设计原则、模板性能优化和模板安全性。Tips: 欢迎评论区讨论,你想要的或者你知道的其他用法哦!!!

I. 简介

A. 什么是 Go text/template

Go text/template 是 Go 语言标准库中的一个模板引擎用于生成文本输出。它使用类似于 HTML 的模板语言,可以数据和模板结合起来,生成最终的文本输出

B. Go text/template 的优点

Go text/template 具有以下优点:

C. Go text/template应用场景

Go text/template 可以用于生成各种类型的文本输出,例如 HTML、XML、JSON、Markdown、Golang 等。它适用于以下场景

II. 模板语法

A. 变量

在 Go text/template 中,变量由双大括号 {{ 和 }} 包围,例如 {{.Name}} 表示一个名为 Name 的变量变量可以是结构体、数组切片映射类型,也可以是自定义类型

  1. 变量定义

在模板中,可以使用{{$}}语句定义一个变量如下所示

{{$name :="qqxhb"}}

这个语句定义了一个名为”name“的变量,其值为”qqxhb”。在模板中,可以使用{{$变量名}}语句引用这个变量,如下所示

{{$name}}

这个语句会输出”qqxhb”。

  1. 变量赋值

在模板中,可以使用{{$}}语句变量赋值,和定义的区别没有冒号如下所示

{{$name ="qqxhb"}}

这个语句字符串qqxhb”赋值给变量,然后使用{{$name}}输出变量的值,即”qqxhb”。

  1. 变量操作

在模板中,可以使用{{range}}语句遍历一个变量的值,如下所示

{{range .Names}}{{.}}{{end}}

这个语句表示遍历“Names“变量的值,并输出每个值。

  1. 变量函数

在模板中,可以使用内置函数来操作变量,如下所示

{{len .Names}}

这个语句表示获取“Names“变量的长度,并输出它的值。
Go text/template提供了丰富的变量操作功能,可以用于生成各种文本格式的输出。通过上述示例,可以更好理解掌握Go text/template中变量的使用方法

B. 控制结构

Go text/template 支持多种控制结构,例如 if、range、with 等。这些控制结构可以用于条件判断循环迭代、变量作用域等。if和range两个非常常用的控制结构,下面是关于Go text/template中if和range的详细用法

  1. if语句

if语句用于根据条件判断是否输出某个内容if语句的语法如下:

{{if .Condition}}...{{end}}

其中,“.Condition”表示一个条件表达式,如果该表达式的值为true,则输出”…”中的内容

示例

{{if .Name}}Hello, {{.Name}}{{end}}

这个语句表示如果”Name”变量的值不为空,则输出”Hello, “和”Name”变量的值。
除了判断空这种场景我们更多的可能是判断等和不等。在Go text/template 中用于等式与不等式判断函数主要有以下六种(均接受两个,分别名arg1 和 arg2 的参数):

eq:当等式 arg1 == arg2 成立时,返回 true,否则返回 false
ne:当不等式 arg1 != arg2 成立时,返回 true,否则返回 false
lt:当不等式 arg1 < arg2 成立时,返回 true,否则返回 false
le:当不等式 arg1 <= arg2 成立时,返回 true,否则返回 false
gt:当不等式 arg1 > arg2 成立时,返回 true,否则返回 false
ge:当不等式 arg1 >= arg2 成立时,返回 true,否则返回 false

示例

{{if eq $age1 $age2}}
    年龄相同
{{else}}
    年龄不相同
{{end}}

或者是组合条件,如:

{{if and (eq $status 1) (ne $title "")}}
    上架
{{else}}
    下架
{{end}}
  1. range语句

range语句用于遍历一个数组、切片映射通道,并输出其中的每个元素range语句的语法如下:

{{range .Array}}...{{end}}
{{range .Slice}}...{{end}}
{{range .Map}}...{{end}}
{{range .Channel}}...{{end}}

其中,“.Array”、“.Slice”、“.Map“和”.Channel“分别表示一个数组、切片映射通道。”…”中的内容表示遍历到的每个元素

示例

{{range .Names}}Hello, {{.}}!{{end}}

这个语句表示遍历”Names“变量的值,并输出”Hello, “和每个值。
遍历也支持两个参数,和go一样有索引遍历,如:

{{range $i, $name := .Names}}
    {{$i}}. {{$name}}
{{end}}
  1. with语句

在模板中,with语句用于设置当前上下文中的变量,下面是关于Go text/template中with的详细用法

  • with语句

with语句用于设置当前上下文中的变量,使得在该语句块中可以直接使用该变量。with语句的语法如下:

{{with .Variable}}...{{end}}

其中,“.Variable”表示一个变量,”…”中的内容表示在该语句块中可以直接使用该变量。

示例

{{with .Person}}
Name: {{.Name}}
Age: {{.Age}}
{{end}}

这个语句表示设置当前上下文中的变量为”Person”,并在该语句块中可以直接使用”Person”变量中的”Name”、”Age”等字段

  • with-else语句

with-else语句用于根据条件判断是否设置当前上下文中的变量。with-else语句的语法如下:

{{with .Variable}}...{{else}}...{{end}}

其中,“.Variable”表示一个变量,如果该变量的值不为空,则设置当前上下文中的变量为该变量,”…“中的内容表示在该语句块中可以直接使用该变量;否则输出”else”后面的”…”中的内容。

示例:

{{with .Person}}{{.Name}}{{else}}Unknown{{end}}

这个语句表示如果”Person”变量的值不为空,则设置当前上下文中的变量为”Person”,并输出”Person”变量中的”Name”字段;否则输出”Unknown”。

C. 函数

Go text/template 内置了一些常用的函数,例如 len、range、printf 等。同时,也支持自定义函数,可以通过 Funcs() 方法注册自定义函数,或者是某个结构的方法。在模板中,函数是一种非常重要的元素,可以用于操作变量、格式化输出等。下面是关于Go text/template中函数的详细用法,包括自定义函数和结构体方法

  1. 内置函数

Go text/template中内置了一些常用的函数,如下所示:

示例:

{{len .Names}}
{{index .Names 0}}
{{printf "%d" .Age}}
{{range .Names}}{{.}}{{end}}
{{with .Person}}{{.Name}}{{end}}

这些语句分别表示获取“Names”变量的长度获取“Names”变量中的第一个元素、格式化输出”Age”变量的值、遍历”Names”变量的值并输出每个值、设置当前上下文中的变量为”Person”并输出”Person”变量中的”Name”字段

  1. 自定义函数

除了内置函数外,还可以自定义函数来操作变量、格式化输出等。自定义函数的语法如下:

{{funcName arg1 arg2 ...}}

其中,”funcName”表示函数名,“arg1”、”arg2″等表示函数的参数。

示例:

{{upper .Name}}

这个语句表示调用名为”upper”的自定义函数,将”Name”变量的值转换大写字母并输出。

自定义函数需要在模板执行之前注册,可以使用text/template包中的Funcs方法注册自定义函数,示例代码如下:

func upper(s string) string {
    return strings.ToUpper(s)
}

t := template.New("test").Funcs(template.FuncMap{
    "upper": upper,
})

这个代码片段定义了一个名为”upper”的自定义函数,并将其注册到名为”test”的模板中。

  1. 结构体方法

除了自定义函数外,还可以使用结构体方法来操作变量、格式化输出等。结构体方法语法如下:

{{.Variable.Method arg1 arg2 ...}}

其中,”.Variable”表示一个变量,”Method“表示该变量的一个方法,“arg1”、”arg2″等表示方法的参数。

示例:

{{.Person.GetName}}

这个语句表示调用“Person”变量的”GetName”方法,并输出该方法的返回值

结构体方法不需要在模板执行之前注册,只需要在结构体定义即可,然后用结构体作为模版参数,代码如下:

type Person struct {
    Name string
}

func (p Person) GetName() string {
    return p.Name
}

t := template.New("test")
t.Parse(&amp;buf,&amp;Person{})

这个代码片段定义了一个名为”Person”的结构体,并在该结构体中定义了一个名为”GetName”的方法。

D. 注释

在模板中,注释是一种非常重要的元素,可以用于注释模板中的代码,方便代码的维护和阅读。下面是关于Go text/template中注释的详细用法

  1. 单行注释

单行注释用于注释一行代码,其语法如下:

{{/* This is a comment */}}

其中,”/“和”/”表示注释的开始和结束,”This is a comment”表示注释的内容。

示例:

{{/* This is a comment */}}Hello, {{.Name}}!

这个语句表示注释”Hello, {{.Name}}!”这一行代码。

  1. 多行注释

多行注释用于注释多行代码,其语法如下:

{{- /* This is a comment
on multiple lines */ -}}

其中,”{{- “和” -}}”表示注释的开始和结束,“This is a comment on multiple lines”表示注释的内容。需要注意的是,注释内容前后的空格会被保留,如果不想保留空格,可以在注释开始和结束标记中使用”-“符号

示例:

{{- /* This is a comment
on multiple lines */ -}}
Hello, {{.Name}}!

这个语句表示注释”Hello, {{.Name}}!”这一行代码,并且注释内容跨越了多行

III. 模板解析和渲染

A. 解析模板

使用 template.New() 函数创建一个新的模板对象,然后使用 Parse() 方法解析模板字符串。如果模板字符串包含多个模板,可以使用 ParseFiles() 或 ParseGlob() 方法解析多个模板文件
在Go语言中,使用text/template包创建和解析模板非常简单。下面是关于Go text/template模板创建和解析注释的详细用法:

在Go text/template中,可以使用New函数创建一个新的模板对象,示例代码如下:

t := template.New("test")

其中,”test”表示模板的名称,可以根据实际情况进行修改

B. 渲染模板

使用 Execute() 方法渲染模板,并将结果输出到指定io.Writer 中。如果模板需要接收参数,可以将参数传递给 Execute() 方法。

err := t.Execute(os.Stdout, map[string]string{"Name": "World"})

其中,”os.Stdout“表示输出流,”map[string]string{“Name”: “World”}”表示模板中的变量。

C. 模板缓存

text/template 支持模板缓存,可以提高模板渲染的效率。使用 template.Must() 函数可以创建一个带有模板缓存的模板对象,如果解析模板失败,会直接 panic

IV. 最佳实践

A. 模板设计原则

设计模板时,应该遵循以下原则

B. 模板性能优化

优化模板性能时,应该注意以下几点:

  • 使用模板缓存:使用 template.Must() 函数创建一个带有模板缓存的模板对象,可以提高模板渲染的效率。
  • 避免重复解析:避免在每次渲染模板时都重新解析模板,可以将模板解析放在初始化阶段
  • 减少模板变量:减少模板中的变量数量,可以提高模板渲染的效率。

C. 模板安全性

在使用模板时,应该注意以下安全问题

V. 总结

Go text/template 是一个简单易用、安全可靠、高效性能、灵活可扩展的模板引擎,适用于生成各种类型的文本输出。在使用模板时,应该遵循最佳实践,注意模板设计原则、模板性能优化和模板安全性。

Tips: 欢迎评论区讨论,你想要的或者你知道的其他用法哦!!!

VI. Tips

如果你在使用过程中,发现某个key存在,就会在解析结果中出现<no value>,你知道如何处理吗?其实很简单了

方案一:通过option配置
//不存在的时候返回空值
template.New("test").Option("missingkey=zero").Parse(tpl)
//不存在的时候报错
template.New("test").Option("missingkey=error").Parse(tpl)

// template: non:1:57: executing "non" at <.Param.xxx>: map has no entry for key "xxx"
方案一:换模版SDK

切换html/template即可,不需要更改任何逻辑效果等同于没有值用零值处理Option("missingkey=zero")

原文地址:https://blog.csdn.net/qq_43792385/article/details/131889077

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_15967.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注