?本文对go语言内置模板处理包"text/template"常用操作汇总进行了详解,非常全面,一次搞定你的问题!还不收藏等啥呢!
目录
type Params struct {
Field string // 取值的key名称
Value string // 值
}
func ConvertParams(params []Params) map[string]interface{} {
ret := make(map[string]interface{}, 0)
for i := range params {
ret[params[i].Field] = params[i].Value
}
fmt.Printf("ret: %+v\n", ret)
return ret
}
// 目标字符串
distStr := "name is {{.name}}, age is {{.age}}"
// 解析列表准备
params := []Params{{Field: "name", Value: "zhangsan"}, {Field: "age", Value: "99"}}
// 创建template对象,并传入目标字符串进行解析
tmpl, err := template.New("basic").Parse(distStr)
if err != nil {
fmt.Println("parse err: ", err)
return
}
fmt.Printf("parse success: %+v\n", tmpl)
// 将解析的模板应用于指定的数据对象,此处将params转为k-v结构并装载到buffer
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, ConvertParams(params))
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String()) // 最终结果
}
speed running:
parse success: &{name:basic Tree:0xc000112240 common:0xc00005c050 leftDelim: rightDelim:}
ret: map[age:99 name:zhangsan]
result: name is zhangsan, age is 99
params := []Params{{Field: "name", Value: "zhangsan"}, {Field: "age", Value: "99"}}
// 此处New的参数必须是待解析的文件名中的一个,随意填写会报: template: x: "x" is an incomplete or empty template
tmpl, err := template.New("demo").ParseFiles("./go_text_template/demo")
if err != nil {
fmt.Println("ParseFiles err: ", err)
return
}
fmt.Printf("ParseFiles success: %+v\n", tmpl)
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, ConvertParams(params))
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String())
}
speed running:
ParseFiles success: &{name:demo Tree:0xc000118120 common:0xc00005c050 leftDelim: rightDelim:}
ret: map[age:99 name:zhangsan]
result: name is zhangsan, age is 99
// 自定义函数
add := func(a, b int, c string) int { fmt.Println("c=", c); return a + b }
// 创建funcMap对象,将自定义函数嵌入
funcMap := template.FuncMap{"add": add}
//此处注意,一定要先绑定函数
tmpl := template.New("methodCall").Funcs(funcMap)
// 注意函数参数之间保持空格,否则会报template: methodCall:1:52: executing "methodCall" at <add>: wrong number of args for add: want 3 got 2
distStr := "打印入参:{{.a}}、{{.b}}、{{.c}} 计算:{{add .a .b \"c\" }}" // 若参数为字符串,形式如c
params := []Params{{Field: "a", Value: 1}, {Field: "b", Value: 2}, {Field: "c", Value: "my val is c"}}
var err error
tmpl, err = tmpl.Parse(distStr)
if err != nil {
fmt.Println("parse err: ", err)
return
}
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, ConvertParams(params))
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String())
}
speed running:
ret: map[a:1 b:2 c:my val is c]
c= c
result: 打印入参:1、2、my val is c 计算:3
type Student struct {
Name string
Age int
}
// 待解析的模板,注意语句形成闭环,否则报错template: range:21: unexpected EOF
distStr := `
第1种:单独遍历每条记录
{{range $info := .}}
{{$info}}
{{- end}}
第2种:仅获取下标
{{range $i, $info := .}}
{{$i}}
{{- end}}
第3种:下标+每条记录
{{range $i, $info := .}}
i: {{$i}} info: {{$info}}
{{- end}}
第4种:得到每条记录的每个字段
{{range $info := .}}
name:{{$info.Name}} age:{{$info.Age}}
{{- end}}
`
// 数据准备
var params []Student
params = []Student{
{Name: "wangwu", Age: 99}, {Name: "zhangsan", Age: 99},
}
tmpl, err := template.New("range").Parse(distStr)
if err != nil {
fmt.Println("parse err: ", err)
return
}
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, params)
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String())
}
speed running:
result:
第1种:单独遍历每条记录
{wangwu 99}
{zhangsan 99}
第2种:仅获取下标
0
1
第3种:下标+每条记录
i: 0 info: {wangwu 99}
i: 1 info: {zhangsan 99}
第4种:得到每条记录的每个字段
name:wangwu age:99
name:zhangsan age:99
type Student struct {
Name string
Age int
IsJuniorStu bool
}
// len可获得长度,index用于以下标获取对应位置的元素,以0开始
// if-end,if-else-end, 条件语句
// eq,判断是否相等,相当于==,用法:{{if eq $info.Age 99}} 表示Age和99是否相等
// lt表示< le表示<= gt表示> ge表示>= ne表示!= eq表示==
distStr := `
数据长度={{len .}}
0号位置的数据: {{index . 1}}
{{range $info := .}}
name:{{$info.Name}} age:{{$info.Age}}
{{if $info.IsJuniorStu}} {{$info.Name}} is a junior student
{{else}} println {{$info.Name}} not a junior student
{{end}}
{{if eq $info.Age 99}} {{$info.Name}} 's age is 99
{{end}}
{{- end}}
`
// 数据准备
var params []Student
params = []Student{
{Name: "wangwu", Age: 99, IsJuniorStu: true}, {Name: "zhangsan", Age: 98, IsJuniorStu: false},
}
tmpl, err := template.New("range").Parse(distStr)
if err != nil {
fmt.Println("parse err: ", err)
return
}
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, params)
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String())
}
speed running:
result:
数据长度=2
0号位置的数据: {zhangsan 98 false}
name:wangwu age:99
wangwu is a junior student
wangwu 's age is 99
name:zhangsan age:98
println zhangsan not a junior student
// 使用:=定义变量
distStr := `
{{ $a1 := "" }}
{{ $a2 := "" }}
{{ $a3 := "ok" }}
{{ $a4 := "ok" }}
{{ $a5 := true }}
{{ $a6 := false }}
{{ $a7 := true }}
or:
{{if or $a1 $a2}}a1||a2为真{{else}}a1||a2为假{{end}}
{{if or $a1 $a3}}a1||a3为真{{else}}a1||a3为假{{end}}
{{if or $a4 $a5}}a4||a5为真{{else}}a4||a5为假{{end}}
and
{{if and $a1 $a2}}a1&&a2为真{{else}}a1&&a2为假{{end}}
{{if and $a1 $a3}}a1&&a3为真{{else}}a1&&a3为假{{end}}
{{if and $a3 $a4}}a3&&a4为真{{else}}a3&&a4为假{{end}}
{{if and $a4 $a5}}a4&&a5为真{{else}}a4&&a5为假{{end}}
{{if and $a4 $a6}}a4&&a6为真{{else}}a4&&a6为假{{end}}
取反:
a1取反={{not $a1}}
a3取反={{not $a3}}
a5取反={{not $a5}}
a6取反={{not $a6}}
`
tmpl, err := template.New("range").Parse(distStr)
if err != nil {
fmt.Println("parse err: ", err)
return
}
buffer := &bytes.Buffer{}
err = tmpl.Execute(buffer, nil)
if err != nil {
fmt.Println("execute err: ", err)
} else {
fmt.Println("result: ", buffer.String())
}
speed running:
or:
a1||a2为假
a1||a3为真
a4||a5为真
and
a1&&a2为假
a1&&a3为假
a3&&a4为真
a4&&a5为真
a4&&a6为假
取反
a1取反=true
a3取反=false
a5取反=false
a6取反=true