go学习笔记——text template


golang可以使用text/template来实现模板生成文本,官方文档:https://pkg.go.dev/text/template

1.变量

可以在模板中定义变量,然后将这些变量赋值到模板的变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import "text/template"
 
// 定义结构体
type Inventory struct {
    Material string
    Count    uint
}
// 赋值
sweaters := Inventory{"wool", 17}
// 定义模板
tmpl, err := template.New("test").Parse(`
    {{.Count}} items are made of {{.Material}}
`)
if err != nil {
    panic(err)
}
// 填充模板
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil {
    panic(err)
}

输出

1
17 items are made of wool

2.if else

1.判断字符串是否相等

1
2
3
4
5
6
7
8
9
10
{{ if eq .Material "wool" }}
  Material is "wool"
{{ else if eq .Material "not wool" }}
  Material is not "wool"
{{ end }}
{{ if eq .Count 17 }}
  Count is 17
{{ else if eq .Count 10 }}
  Count is not 10
{{ end }}

输出

1
2
3
Material is "wool"
 
Count is 17

2.多条件,与或非

1
2
3
{{ if or (eq .Material "not wool") (eq .Count 17) }}
  Count is 17
{{ end }}

输出

1
Count is 17

3.for循环

1.遍历数组

在for循环中使用其他变量的时候,要用{{$.xxx}}

取得index和value,使用{{$index}}和{{$value}}

1
2
3
{{range $index, $value := .Ips}}
   index: {{$index}}, material: {{$.Material}}, value: {{$value}}
{{end}}

输出

1
2
3
index: 0, material: wool, value: 192.168.0.1
         
index: 1, material: wool, value: 192.168.0.2

2.遍历map

同样也可以使用for循环遍历map,取得key和value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type Inventory struct {
    Material string
    Count    uint
    Ips      []string
    Maps     map[string]string
}
sweaters := Inventory{
    "wool",
    17,
    []string{"192.168.0.1", "192.168.0.2"},
    map[string]string{
        "key":   "hello",
        "value": "world",
    },
}
tmpl, err := template.New("test").Parse(`
    {{range $key, $value := .Maps}}
       key: {{$key}}, material: {{$.Material}}, value: {{$value}}
    {{end}}
`)
if err != nil {
    panic(err)
}
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil {
    panic(err)
}

4.函数

1.len函数

判断数组的长度是否等于1,其中Ips可以是切片或者map

1
2
3
4
5
6
7
{{if eq (len .Ips) 1}}
len=1
{{else if eq (len .Ips) 2}}
len=2
{{else}}
other
{{end}}

2.index函数

可以使用index函数获得数组特定下标的值

1
{{index .Ips 0}}

如果和eq函数一起使用

1
2
3
{{if or (eq (index .Ips 0) "192.168.0.1") (eq (index .Ips 1) "192.168.0.2")}}
 
{{end}}

3.for循环下标从1开始

参考:golang template(数组循环、在循环内使用外部变量、索引从1开始)

4.自定义函数

可以自定义函数来自己实现函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package main
 
import (
    "bytes"
    "strings"
    "text/template"
)
 
func main() {
    type Inventory struct {
        Material string
        Count    uint
        Ips      []string
        Maps     map[string]string
    }
    sweaters := Inventory{
        "test1,test2",
        17,
        []string{"192.168.0.1", "192.168.0.2"},
        map[string]string{
            "key":   "hello",
            "value": "world",
        },
    }
    tmpl := template.New("test")
    funcs := template.FuncMap{
        "hasSuffix":   strings.HasSuffix,
        "split":       strings.Split,
        "containItem": containItem,
        "renderTemplate": func(name string, data interface{}) (string, error) {
            var buf bytes.Buffer
            err := tmpl.ExecuteTemplate(&buf, name, data)
            return buf.String() + " test", err
        },
    }
    temp, err := tmpl.Funcs(funcs).Parse(
        `
        {{if hasSuffix .Material "test2"}}
            hasSuffix
        {{end}}
    `)
    if err != nil {
        panic(err)
    }
    var output bytes.Buffer
    err = temp.Execute(&output, sweaters)
    if err != nil {
        panic(err)
    }
    str := output.String()
    println(str)
}
 
func containItem(slice []string, item string) bool {
    for _, v := range slice {
        if v == item {
            return true
        }
    }
    return false
}

判断字符串是否包含特定后缀

1
2
3
{{if hasSuffix .Material "test2"}}
    hasSuffix
{{end}}

将字符串以特定字符切分成数组,然后遍历

1
2
3
4
{{- $items := split .Material "," -}}
{{- range $index, $item := $items -}}
    {{$item}}
{{end}}

输出

1
2
test1
                test2

判断切片是否包含特定字符串

1
2
3
{{if containItem .Ips "192.168.0.1"}}
    containItem
{{end}}

5.其他

1.注释

1
{{/* 注释 */}}

2.子模板

可以在template中使用define关键字定义一个子模板,然后使用template关键字添加这个子模板

1
2
3
4
5
6
start define a template
{{- define "T1" -}}
   define a template
{{- end -}}
{{template "T1" .}}
end define a template

输出

1
2
3
4
5
6
start define a template
 
 
        define a template
 
end define a template

3.去除空格

可以看到上面渲染出来的字符串中有很多的空格,可以使用 - 来去掉多余的空格

比如去掉前面的空格

1
{{- "start define a template"}}

去掉后面的空格

1
{{"start define a template"}}

去掉模板前后,和模板中的空格

1
2
3
4
5
6
{{- "start define a template" -}}
{{define "T1" -}}
define a template
{{- end}}
{{- template "T1" . -}}
{{- "end define a template" -}}

输出

1
start define a templatedefine a templateend define a template

4.将子模板定义成一个变量,并使用函数进行处理后输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main
 
import (
    "bytes"
    "text/template"
)
 
func main() {
    type Inventory struct {
        Material string
        Count    uint
        Ips      []string
        Maps     map[string]string
    }
    sweaters := Inventory{
        "wool",
        17,
        []string{"192.168.0.1", "192.168.0.2"},
        map[string]string{
            "key":   "hello",
            "value": "world",
        },
    }
    tmpl := template.New("test")
    funcs := template.FuncMap{
        "renderTemplate": func(name string, data interface{}) (string, error) {
            var buf bytes.Buffer
            err := tmpl.ExecuteTemplate(&buf, name, data)
            return buf.String() + " test", err
        },
    }
    temp, err := tmpl.Funcs(funcs).Parse(
        `
        {{define "T1" -}}
        define a template
        {{- end}}
 
        {{define "T111"}}
            {{- $message := renderTemplate "T1" . -}}
            {{$message}}
        {{end}}
 
        {{template "T111" .}}
    `)
    if err != nil {
        panic(err)
    }
    var output bytes.Buffer
    err = temp.Execute(&output, sweaters)
    if err != nil {
        panic(err)
    }
    str := output.String()
    println(str)
}

 

posted @   tonglin0325  阅读(53)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示