更多个人笔记见:
github个人笔记仓库
gitee 个人笔记仓库
个人学习,学习过程中还会不断补充~ (后续会更新在github上)
Template 模板
基本示例
package main
import (
"fmt"
"html/template"
"os"
)
// 定义数据结构
type Person struct {
Name string
Age int
Email string
IsAdmin bool
}
type Company struct {
Name string
Employees []Person
Founded int
}
func main() {
// 示例1:基本语法演示
basicTemplateDemo()
// 示例2:条件判断和循环
conditionalAndLoopDemo()
// 示例3:HTML模板
htmlTemplateDemo()
// 示例4:Must的使用
mustTemplateDemo()
}
// 基本语法演示
func basicTemplateDemo() {
fmt.Println("=== 基本语法演示 ===")
// {{.}} 表示当前数据对象
tmpl1 := `Hello {{.}}!`
t1 := template.Must(template.New("basic").Parse(tmpl1))
t1.Execute(os.Stdout, "World")
fmt.Println()
// {{.Name}} 访问结构体字段
person := Person{Name: "张三", Age: 30, Email: "zhangsan@example.com"}
tmpl2 := `姓名: {{.Name}}, 年龄: {{.Age}}, 邮箱: {{.Email}}`
t2 := template.Must(template.New("person").Parse(tmpl2)) //person 是模板名字
t2.Execute(os.Stdout, person) //对应的结构体
fmt.Println("\n")
}
// 条件判断和循环演示
func conditionalAndLoopDemo() {
fmt.Println("=== 条件判断和循环演示 ===")
company := Company{
Name: "科技公司",
Founded: 2020,
Employees: []Person{
{Name: "李四", Age: 25, Email: "lisi@example.com", IsAdmin: true},
{Name: "王五", Age: 28, Email: "wangwu@example.com", IsAdmin: false},
{Name: "赵六", Age: 32, Email: "zhaoliu@example.com", IsAdmin: false},
},
}
// 使用 {{range .}} 循环和 {{if}} 条件判断
// {{- 和 -}} 用于去除空白字符
tmpl := `公司: {{.Name}} (成立于 {{.Founded}}年)
员工列表:
{{- range .Employees}}
- 姓名: {{.Name}}
{{- if .IsAdmin}} (管理员){{else}} (普通员工){{end}}
年龄: {{.Age}}, 邮箱: {{.Email}}
{{- end}}
`
//通过IsAdmin 进行判断是否是管理员
t := template.Must(template.New("company").Parse(tmpl))
t.Execute(os.Stdout, company) //传入的 company 是一个大结构体,里面包括 Employees 列表
fmt.Println()
}
// HTML模板演示
func htmlTemplateDemo() {
fmt.Println("=== HTML模板演示 ===")
// HTML模板会自动转义特殊字符
htmlTmpl := `
<!DOCTYPE html>
<html>
<head>
<title>{{.Name}} - 员工列表</title>
</head>
<body>
<h1>{{.Name}}</h1>
<p>成立年份: {{.Founded}}</p>
<h2>员工信息</h2>
<table border="1">
<tr>
<th>姓名</th>
<th>年龄</th>
<th>邮箱</th>
<th>角色</th>
</tr>
{{- range .Employees}}
<tr>
<td>{{.Name}}</td>
<td>{{.Age}}</td>
<td>{{.Email}}</td>
<td>
{{- if .IsAdmin -}}
<span style="color: red;">管理员</span>
{{- else -}}
普通员工
{{- end -}}
</td>
</tr>
{{- end}}
</table>
</body>
</html>
`
company := Company{
Name: "示例科技公司",
Founded: 2020,
Employees: []Person{
{Name: "张三", Age: 30, IsAdmin: true},
{Name: "李四", Age: 25, IsAdmin: false},
},
}
// 创建HTML文件
file, err := os.Create("company.html") //创建接收的文件
if err != nil {
panic(err)
}
defer file.Close()
t := template.Must(template.New("html").Parse(htmlTmpl))
t.Execute(file, company) //这里不是 os.stdout输出了,而是输出到了文件中
fmt.Println("HTML文件已生成: company.html")
}
// Must的使用演示
func mustTemplateDemo() {
fmt.Println("=== Must使用演示 ===")
// Must会在模板解析失败时直接panic
// 这是一个正确的模板
validTemplate := `Hello {{.Name}}!`
t1 := template.Must(template.New("valid").Parse(validTemplate))
person := Person{Name: "测试用户"}
fmt.Print("正确模板输出: ")
t1.Execute(os.Stdout, person)
fmt.Println()
// 演示错误处理(注释掉以避免程序崩溃)
/*
// 这是一个错误的模板语法,Must会直接panic
invalidTemplate := `Hello {{.Name!` // 缺少右括号
t2 := template.Must(template.New("invalid").Parse(invalidTemplate))
*/
// 不使用Must的错误处理方式
invalidTemplate := `Hello {{.Name!` //这里缺少了右边括号
t2, err := template.New("invalid").Parse(invalidTemplate) //没有用 Must,用 Must 会 panic 导致程序退出
if err != nil {
fmt.Printf("模板解析错误: %v\n", err)
} else {
t2.Execute(os.Stdout, person)
}
}
语法
1. 基本输出语法
{{.}}
: 输出当前数据对象{{.Name}}
: 输出结构体的Name字段{{.Field.SubField}}
: 访问嵌套字段
2. 控制结构
{{if .IsAdmin}}...{{else}}...{{end}}
: 条件判断{{range .Employees}}...{{end}}
: 循环遍历{{with .Field}}...{{end}}
: 设置上下文
3. 空白字符控制
{{-
: 去除左侧空白字符-}}
: 去除右侧空白字符{{- if .IsAdmin -}}
: 去除两侧空白字符
4. Must函数
template.Must()
: 在模板解析失败时直接panic- 适用于程序启动时的模板初始化
- 类似于panic的检验机制
- 如果需要接受错误就不要用 Must