您的位置:首页 > 财经 > 产业 > 国内装修公司排名_支付宝小程序定制_手机怎么搭建网站_百度资源站长平台

国内装修公司排名_支付宝小程序定制_手机怎么搭建网站_百度资源站长平台

2025/1/11 8:44:36 来源:https://blog.csdn.net/a18792721831/article/details/144357215  浏览:    关键词:国内装修公司排名_支付宝小程序定制_手机怎么搭建网站_百度资源站长平台
国内装修公司排名_支付宝小程序定制_手机怎么搭建网站_百度资源站长平台

Go-知识 模板

  • 1. 介绍
  • 2. Text/template 包
  • 3. Html/template 包
  • 4. 模板语法
    • 4.1 模板标签
    • 4.2 添加注释
    • 4.3 访问变量
    • 4.4 访问方法
    • 4.5 模板变量
    • 4.6 访问函数
    • 4.7 数据渲染
    • 4.8 条件判断
    • 4.9 循环遍历
    • 4.10 嵌入子模板
    • 4.11 局部变量
    • 4.12 输出字符串
    • 4.13 预定义的全局函数
    • 4.14 比较函数

1. 介绍

fmt.Printf可以做到格式化输出,这对于简单的例子已经足够,但是有时候还需要更加复杂的输出格式,甚至需要将格式与代码分离开来。这个时候就可以使用模板(Template)。

2. Text/template 包

text/template包提供了处理文字模板与数据的功能,模板引擎。

所谓模板引擎,就是将模板和数据进行渲染的输出格式化后的字符串程序。

使用模板引擎分为三步:

  1. 创建模板对象
  2. 加载模板
  3. 执行渲染模板

比如如下例子:

package gostudyimport ("os""testing""text/template"
)func TestTe(t *testing.T) {templ := `
{{range.}}--------------------------------------
Name:  {{.Name}}
Age:   {{.Age}}
{{end}}
`tp := template.Must(template.New("templ").Parse(templ))type Person struct {Name stringAge  int}persons := []Person{{"gw", 18},{"lx", 20},{"ly", 21},}if err := tp.Execute(os.Stdout, persons); err != nil {t.Log(err)}
}

执行结果如下

请添加图片描述

在代码中, templ 就是一段模板文字,然后使用程序中的数据,渲染模板,填充模板中的占位,最后得到完整的输出。

除了将模板文字在程序中写死,也可以将模板与程序分离,也就是格式和数据分离,使用不同的文件存储

首先创建一个文件用于存储模板文字,后缀可以自定义

在这里插入图片描述

然后在程序中直接加载模板文件

func TestTeTxt(t *testing.T) {tp := template.Must(template.ParseFiles("./name_age.tpl"))type Person struct {Name stringAge  int}persons := []Person{{"gw", 18},{"lx", 20},{"ly", 21},}if err := tp.Execute(os.Stdout, persons); err != nil {t.Log(err)}
}

执行结果与之前完全相同

如果要加载多个模板文件,有两种方式:枚举方式,正则方式 以及目录方式

枚举方式 tp := template.Must(template.ParseFiles("./name_age1.tpl", "./name_age2.tpl","./name_age3.tpl"))

正则方式 tp := template.Must(template.ParseGlob("./*.tpl"))

目录方式

	files, err := filepath.Glob("./*.html.tmpl")if err != nil {log.Fatalf("Error while globbing files: %v", err)}tp := template.Must(template.ParseFS(os.DirFS("./)"), files...))

template.Must 主要是检测模板是否正确。

3. Html/template 包

text/template类似,html/template主要提供支持 HTML 模板的功能,使用方法差不多。

创建一个index.html.tmpl 文件

在这里插入图片描述

模板内容如下

<!doctype html><head><meta charset="UTF-8"><meta name="Author" content=""><meta name="Keywords" content=""><meta name="Description" content=""><title>Go</title></head><body>{{.}}</body>
</html>

然后创建一个web服务端

func TestHt(t *testing.T) {tp := template.Must(template.ParseFiles("./index.html.tmpl"))http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {tp.Execute(writer, "Hello")})http.ListenAndServe(":8080", nil)}

访问

在这里插入图片描述

在多模板的时候,可以定义模板的名字,然后在执行的时候,指定模板渲染

比如

在这里插入图片描述

使用 {{ define "index"}} 定义了模板的name

然后加载模板的时候,加载全部的模板,指定index1 执行

func TestHt(t *testing.T) {files, err := filepath.Glob("./*.html.tmpl")if err != nil {log.Fatalf("Error while globbing files: %v", err)}tp := template.Must(template.ParseFS(os.DirFS("./"), files...))http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {tp.ExecuteTemplate(writer, "index1", "Hello")})http.ListenAndServe(":8080", nil)
}

执行并访问

在这里插入图片描述

同时在模板文件之间可以进行嵌套

比如如下模板

在这里插入图片描述

然后修改index1.html.tmpl

在这里插入图片描述

重启web

在这里插入图片描述

4. 模板语法

4.1 模板标签

{{}} 就是模板标签,中间是模板的语法内容。

4.2 添加注释

{{/* 注释 */}}, 使用 {{/**/}} 包含注释的内容。

    2. 注释 `{{/* 注释 */}}`: <br/>{{/* 这是一条注释 */}}<br/>

4.3 访问变量

{{.}} 此标签输出当前对象值。

{{.Name}} 表示输出对象中字段或方法名为 Name 的值。

需要注意,如果方法定义为 func (p Person)Name() string 那么,在渲染模板的时候,一定是值对象。

如果方法定义为 func (p *Person)Name() string 那么,在渲染模板时,一定是指针对象。

如果 Name 是匿名字段,那么还可以继续访问内部字段,比如 {{.Name.First}}

如果存在一个方法Say,并且是 Name 的方法。

假设Say返回对象,那么可以继续访问{{.Name.Say.Field}}

{{.F1.F2.F3}},F 可以是方法也可以是结构体。(要小心空指针)

    1. 输出当前对象的值 `{{ . }}` : <br/>{{ . }}<br/>3. 变量: <br/>3.1 当前对象 `\{\{ . \}\}` : {{ . }} <br/>属性 NameStr : {{ .NameStr }} <br/>3.2 方法 `\{\{ .Name \}\}` : {{ .Name }} <br/>3.3 定义变量 `\{\{ $x := "test" \}\}` : {{ $x := "test" }} <br/>3.4 访问变量 `\{\{ $x \}\}` : {{ $x }} <br/>3.5 定义变量 n , 接收当前对象的值,然后传递给 ForName 函数,返回 对象并打印输出: <br/>`\{\{ $n := .NameStr \}\}`,`\{\{ .ForName $n \}\}` <br/>实际上等价于 `\{\{ .ForName \}\}` <br/>{{ $n := .NameStr }} <br/>{{ $n }} <br/>{{ .ForName $n }} <br/>{{ .ForName .NameStr }} <br/>

在这里插入图片描述

4.4 访问方法

{{.Method param1 param2 param3}} 调用方法 Method,后面的 param是调用参数

4.5 模板变量

在模板中定义变量,变量名称用字母和数据组成,并加上 $ 前缀,采用简短赋值。

比如 {{ $x := "OK" }}, {{ $y := "yes"}}

访问定义的模板变量

{{ $x }} 用于输出在模板中定义的名称为 x 的变量,当 定义的变量是个结构体的时候,可以连续访问

4.6 访问函数

  • 函数:在 Go 中,函数是独立的,必须显式地注册到模板中,以便在模板中使用。
  • 方法:方法是与特定类型(如结构体)关联的。当你在模板中使用结构体的实例时,模板引擎会自动识别该实例的方法。

在模板中要使用函数,必须先注册,不注册的话,是不能使用的

{{ FuncName1 }} 调用标签名字为 FuncName1 的函数,等价于执行 FuncName1()

{{ FuncName1 param1 param2 ..}} 调用带有参数的函数

{{ FuncName1 . }} 等价于 FuncName1(this),这里的 this 取决于传递给模板渲染时的数据。

{{ .|FuncName1 }}{{ FuncName1 . }}

      3.6 访问函数 `\{\{ SayName .NameStr \}\}`: {{ SayName .NameStr }} <br/>3.7 访问函数 `\{\{ .|Say  \}\}` : {{ .|Say }} <br/>访问函数 `\{\{ Say . \}\}` : {{ Say . }} <br/>

在这里插入图片描述

4.7 数据渲染

在模板渲染的时候,如果想使用复杂的数据结构或者需要渲染很多数据,那么可以使用复杂struct 或者map进行传递。

如果使用map

	data := map[string]interface{}{"NameStr": "xiaomei","Age":     18,"Country": "China",}

模板

<h1>{{ SayHello .NameStr }}!</h1>
<p>Age: {{ .Age }}</p>
<p>Country: {{ .Country }}</p>

使用struct通常更具可读性和类型安全,而使用 map 则提供了更大的灵活性。

4.8 条件判断

{{ if condition }} T1 {{ end }} 结构为 {{ if ... }} ... {{ end }},类似go里面单个 if

{{ if condition }} T1 {{ else }} T2 {{ end }}结构为{{ if ... }} ... {{ else }} ... {{ end }},类似 go 里面的 if-else

{{ if condition }} T1 {{ else if con2}} T2 ... {{ else }} Tn {{ end }} 类似go 里面的多if分支

if 后面可以是一个条件表达式,条件可以是调用函数,方法等等,也可以是一个字符串变量或者布尔值变量。

当是字符串变量时,空字符串为 false,非空为true。

    4. 条件 <br/>Sex = {{ .Sex }}, Age = {{ .Age }} <br/>单个 if : {{ if eq .Sex "woman" }}女{{ else }}男{{ end }}<br/>多个 if :{{ if and  (eq .Sex "woman") (le .Age 18 ) }}少女{{ else if and (eq .Sex "man") (le .Age 18 ) }}少男{{ else }}其他{{ end }}

在这里插入图片描述

4.9 循环遍历

{{ range $k,$v := .Var }} T {{ end }} range … end 结构内部如果要使用外部的变量,需要在外部变量的名字前加 $

{{ range .var }} {{ . }} {{ end }} 将遍历值直接展示出来

{{ range condition }} T {{ else }} TT {{ end }} 当没有可遍历的值的时候,执行 else 部分

5. 循环遍历 <br/>遍历数组直接输出<br/>{{ range .Msg }}{{ . }} ,{{ end }}<br/>遍历map输出<br/>{{ range .MsgMap }}{{ . }}{{ end }}<br/>遍历输出 k,v <br/>{{ range $k,$v := .MsgMap }}( {{ $k }} , {{ $v }} ) <br/>{{ end }}<br/>定义外部变量 {{ $t := "say:" }} <br/>使用外部变量 <br/>{{ range $k,$v := .MsgMap }}{{ $t }} : {{ $k }} => {{ $v }} <br/>{{ end }}<br/>带有条件的循环遍历<br/>{{ range $k, $v := .MsgMap }}{{ if le $v 3 }}{{ $k }} => {{ $v }} <br/>{{ else }}({{$k}},{{$v}})<br/>{{ end }}{{ end }}<br/>

输出

在这里插入图片描述

4.10 嵌入子模板

{{ template "name"}} 嵌入名称为 “name” 的子模板。 使用前必须使用 {{ define "name"}}{{ end }} 进行定义

{{ define "div" }}
<div><b> World </b>
</div>
{{ end }}
    6. 子模板 <br/>{{ template "div" }}

在这里插入图片描述

子模板可以嵌套多次,嵌套多个

4.11 局部变量

{{ with ...}} T {{ end }} 将值赋值给标签内部的 .

{{ with ...}} T {{ else }} TT {{end}} 如果值为空,执行 else

7. 局部变量 <br/>{{ with .NameStr }}nameStr = {{ . }}<br/>{{ end }}<br/>带有 else 的 with <br/>{{ with "" }}不空{{ else }}空{{ end }}<br/>

在这里插入图片描述

4.12 输出字符串

{{ "\"output\""}} 转义输出

` 可以使字符串原样输出

{{ pintf "%q" "output"}} 函数调用输出 等价于 printf("%q", "output")

{{ "output"|printf "%q"}} 另一种调用方式 printf("%q","output")

{{ printf "%q" (print "out" "put")}} 多层调用 printf("%q", print("out","put"))

{{ "put" | print "%s%s" "out" | printf "%q"}} 另一种写法printf("%q", print("%s%s", "out","put"))

{{ "output" | prinf "%s" | printf "%q"}} 等价于 printf("%q", printf("%s", "output"))

{{ with "output"}} {{ printf "%q" .}} {{ end }} 使用 .的with 写法

{{ with $x := "output" | printf "%q"}} {{ $x }} {{ end }} 使用通道的with写法

{{ with $x := "output"}} {{ $x | printf "%q"}} {{ end }} 另一种写法

8. 字符串<br/>{{ "\"output\"" }} <br/>{{ `"output"` }} <br/>{{ `{{ printf "%q" "output" }}` }} {{ printf "%q" "output" }}<br/>{{ with "output" }} {{ . | printf "%q" }} {{ end }} <br/>

在这里插入图片描述

4.13 预定义的全局函数

{{ and x y}} 如果 x 为真,返回 y,否则返回 x

{{ or x y }} 如果 x 为真,返回x ,否则返回 y

{{ call func param1 param2 ...}} 调用函数,函数返回值限定为 1个或者2个(第二个必须是 error)

如果传递的参数与函数定义的不匹配,或者返回的 error 不为 nil ,停止执行

{{html}} 转义文本中的 html 标签

{{ index map 1 2 3}} 返回 index 后面的第一个参数的某个索引对应的元素值,其余参数作为索引值。必须是 map,数组,slice

{{ js }} 返回用 javascript 的 escape 处理后的文本

{{ len x }} 返回长度

{{ not x}} 取反

{{ print }} fmt.Sprint 的别名

{{ printf }} fmt.Sprintf 的别名

{{ println }} fmt.Sprintln的别名

{{ urlquery }} 在URL查询中嵌入到形参中的文本转义,类似 urlencode

    9. 预定义<br/><p>and: {{ and true "Y" }}</p><p>or: {{ or false "Y" }}</p><p>len: {{ len .Msg }}</p><p>not: {{ not false }}</p><p>print: {{ print "Hello, " "World!" }}</p><p>printf: {{ printf "Hello, %s!" "World" }}</p><p>println: {{ println "Hello," "World!" }}</p><p>index: {{ index .MsgMap "two" }}</p><p>call: {{ call .SayN "xiaomei" }}</p>

在这里插入图片描述

4.14 比较函数

{{ eq arg1 arg2}} :=> arg1 == arg2

{{ ne arg1 arg2 }} :=> arg1 != arg2

{{ lt arg1 arg2 }} :=> arg1 < arg2

{{ le arg1 arg2 }} :=> arg1 <= arg2

{{ gt arg1 arg2 }} :=> arg1 > arg2

{{ ge arg1 arg2 }} :=> arg1 >= arg2

比较函数对任何零值返回 false ,非零值返回 true 。

比较函数每次只接受两个参数

{{ eq arg1 arg2 arg3 arg4}} 等价于 arg1 == arg2 || arg1 == arg3 || arg1 == arg4

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com