当前位置: 首页 > news >正文

Go Web 编程快速入门 07.3 - 模板(3):Action、函数与管道

在前两章中,我们学习了Go模板的基础语法和解析执行机制。本章将深入探讨模板的核心特性:Action动作系统、自定义函数和管道操作。这些高级特性让模板具备了强大的数据处理和逻辑控制能力。

1. Action动作系统深入

1.1 Action基础与分类

package mainimport ("fmt""html/template""text/template""strings""time""reflect""sync"
)// ActionType Action类型枚举
type ActionType intconst (ActionVariable ActionType = iota // 变量动作ActionIf                        // 条件动作ActionRange                     // 循环动作ActionWith                      // 上下文动作ActionTemplate                  // 模板动作ActionBlock                     // 块动作ActionDefine                    // 定义动作ActionFunction                  // 函数动作
)// ActionInfo Action信息
type ActionInfo struct {Type        ActionType `json:"type"`         // 动作类型Name        string     `json:"name"`         // 动作名称Description string     `json:"description"`  // 动作描述Syntax      string     `json:"syntax"`       // 语法格式Example     string     `json:"example"`      // 使用示例Notes       []string   `json:"notes"`        // 注意事项
}// ActionRegistry Action注册表
type ActionRegistry struct {actions map[ActionType]*ActionInfomutex   sync.RWMutex
}// NewActionRegistry 创建Action注册表
func NewActionRegistry() *ActionRegistry {registry := &ActionRegistry{actions: make(map[ActionType]*ActionInfo),}// 注册内置Actionregistry.registerBuiltinActions()return registry
}// registerBuiltinActions 注册内置Action
func (ar *ActionRegistry) registerBuiltinActions() {actions := []*ActionInfo{{Type:        ActionVariable,Name:        "变量输出",Description: "输出变量值,支持字段访问和索引操作",Syntax:      "{{.Variable}} {{.Field.SubField}} {{index .Array 0}}",Example:     "{{.Name}} {{.User.Email}} {{index .Items 0}}",Notes:       []string{"支持链式访问", "自动HTML转义", "nil值输出为空"},},{Type:        ActionIf,Name:        "条件判断",Description: "根据条件执行不同的模板分支",Syntax:      "{{if condition}}...{{else if condition}}...{{else}}...{{end}}",Example:     "{{if .IsActive}}激活{{else}}未激活{{end}}",Notes:       []string{"支持嵌套", "支持多个else if", "条件为false/nil/0/空字符串时为假"},},{Type:        ActionRange,Name:        "循环遍历",Description: "遍历数组、切片、映射或通道",Syntax:      "{{range .Items}}...{{else}}...{{end}}",Example:     "{{range .Users}}{{.Name}}{{end}}",Notes:       []string{"支持索引访问", "空集合执行else分支", "可以使用break和continue"},},{Type:        ActionWith,Name:        "上下文切换",Description: "改变当前上下文,简化变量访问",Syntax:      "{{with .Variable}}...{{else}}...{{end}}",Example:     "{{with .User}}{{.Name}} {{.Email}}{{end}}",Notes:       []string{"变量为nil时执行else分支", "简化深层访问", "可以嵌套使用"},},{Type:        ActionTemplate,Name:        "模板调用",Description: "调用其他已定义的模板",Syntax:      "{{template \"name\" .}} {{template \"name\" pipeline}}",Example:     "{{template \"header\" .}} {{template \"user\" .CurrentUser}}",Notes:       []string{"支持传递数据", "模板必须已定义", "支持递归调用"},},{Type:        ActionBlock,Name:        "块定义",Description: "定义可重写的模板块",Syntax:      "{{block \"name\" .}}default content{{end}}",Example:     "{{block \"content\" .}}默认内容{{end}}",Notes:       []string{"可以被重新定义", "支持默认内容", "用于模板继承"},},{Type:        ActionDefine,Name:        "模板定义",Description: "定义命名模板供其他模板使用",Syntax:      "{{define \"name\"}}...{{end}}",Example:     "{{define \"header\"}}页面头部{{end}}",Notes:       []string{"全局可见", "可以递归调用", "支持参数传递"},},{Type:        ActionFunction,Name:        "函数调用",Description: "调用内置或自定义函数",Syntax:      "{{function arg1 arg2}} {{arg1 | function}}",Example:     "{{add 1 2}} {{.Name | upper}}",Notes:       []string{"支持管道操作", "支持多参数", "支持链式调用"},},}for _, action := range actions {ar.actions[action.Type] = action}
}// GetAction 获取Action信息
func (ar *ActionRegistry) GetAction(actionType ActionType) *ActionInfo {ar.mutex.RLock()defer ar.mutex.RUnlock()return ar.actions[actionType]
}// ListActions 列出所有Action
func (ar *ActionRegistry) ListActions() []*ActionInfo {ar.mutex.RLock()defer ar.mutex.RUnlock()var actions []*ActionInfofor _, action := range ar.actions {actions = append(actions, action)}return actions
}// PrintActionGuide 打印Action使用指南
func (ar *ActionRegistry) PrintActionGuide() {fmt.Println("=== Go模板Action使用指南 ===\n")actions := ar.ListActions()for i, action := range actions {fmt.Printf("%d. %s\n", i+1, action.Name)fmt.Printf("   描述: %s\n", action.Description)fmt.Printf("   语法: %s\n", action.Syntax)fmt.Printf("   示例: %s\n", action.Example)if len(action.Notes) > 0 {fmt.Printf("   注意事项:\n")for _, note := range action.Notes {fmt.Printf("     • %s\n", note)}}fmt.Println()}
}

1.2 高级Action使用示例

// ActionDemoData 演示数据结构
type ActionDemoData struct {Title       string                 `json:"title"`Users       []User                 `json:"users"`Products    []Product              `json:"products"`Settings    map[string]interface{} `json:"settings"`Stats       Statistics             `json:"stats"`CurrentUser *User                  `json:"current_user"`IsLoggedIn  bool                   `json:"is_logged_in"`Categories  []Category             `json:"categories"`
}// User 用户结构
type User struct {ID       int       `json:"id"`Name     string    `json:"name"`Email    string    `json:"email"`Role     string    `json:"role"`Active   bool      `json:"active"`JoinedAt time.Time `json:"joined_at"`Profile  Profile   `json:"profile"`
}// Profile 用户资料
type Profile struct {Avatar   string `json:"avatar"`Bio      string `json:"bio"`Location string `json:"location"`Website  string `json:"website"`
}// Product 产品结构
type Product struct {ID          int     `json:"id"`Name        string  `json:"name"`Price       float64 `json:"price"`Category    string  `json:"category"`InStock     bool    `json:"in_stock"`Rating      float64 `json:"rating"`ReviewCount int     `json:"review_count"`
}// Category 分类结构
type Category struct {ID       int    `json:"id"`Name     string `json:"name"`ParentID *int   `json:"parent_id"`Level    int    `json:"level"`
}// Statistics 统计信息
type Statistics struct {TotalUsers    int `json:"total_users"`ActiveUsers   int `json:"active_users"`TotalProducts int `json:"total_products"`TotalOrders   int `json:"total_orders"`
}// ActionDemo Action演示器
type ActionDemo struct {registry *ActionRegistrydata     *ActionDemoData
}// NewActionDemo 创建Action演示器
func NewActionDemo() *ActionDemo {return &ActionDemo{registry: NewActionRegistry(),data:     createDemoData(),}
}// createDemoData 创建演示数据
func createDemoData() *ActionDemoData {users := []User{{ID:       1,Name:     "张三",Email:    "zhang@example.com",Role:     "admin",Active:   true,JoinedAt: time.Now().Add(-30 * 24 * time.Hour),Profile: Profile{Avatar:   "/avatars/zhang.jpg",Bio:      "系统管理员",Location: "北京",Website:  "https://zhang.dev",},},{ID:       2,Name:     "李四",Email:    "li@example.com",Role:     "user",Active:   true,JoinedAt: time.Now().Add(-15 * 24 * time.Hour),Profile: Profile{Avatar:   "/avatars/li.jpg",Bio:      "前端开发工程师",Location: "上海",Website:  "https://li.dev",},},{ID:       3,Name:     "王五",Email:    "wang@example.com",Role:     "user",Active:   false,JoinedAt: time.Now().Add(-60 * 24 * time.Hour),Profile: Profile{Avatar:   "/avatars/wang.jpg",Bio:      "后端开发工程师",Location: "深圳",Website:  "",},},}products := []Product{{ID: 1, Name: "Go编程指南", Price: 89.99, Category: "书籍", InStock: true, Rating: 4.8, ReviewCount: 156},{ID: 2, Name: "Web开发实战", Price: 79.99, Category: "书籍", InStock: true, Rating: 4.6, ReviewCount: 89},{ID: 3, Name: "云原生架构", Price: 99.99, Category: "书籍", InStock: false, Rating: 4.9, ReviewCount: 234},}categories := []Category{{ID: 1, Name: "技术", ParentID: nil, Level: 1},{ID: 2, Name: "编程语言", ParentID: &[]int{1}[0], Level: 2},{ID: 3, Name: "Web开发", ParentID: &[]int{1}[0], Level: 2},}return &ActionDemoData{Title:    "Action演示系统",Users:    users,Products: products,Settings: map[string]interface{}{"theme":      "dark","language":   "zh-CN","page_size":  10,"enable_api": true,},Stats: Statistics{TotalUsers:    len(users),ActiveUsers:   2,TotalProducts: len(products),TotalOrders:   45,},CurrentUser: &users[0],IsLoggedIn:  true,Categories:  categories,}
}// DemoVariableActions 演示变量Action
func (ad *ActionDemo) DemoVariableActions() {fmt.Println("=== 变量Action演示 ===\n")// 基础变量访问模板basicTemplate := `
基础变量访问:
- 标题: {{.Title}}
- 是否登录: {{.IsLoggedIn}}
- 用户总数: {{.Stats.TotalUsers}}字段链式访问:
- 当前用户名: {{.CurrentUser.Name}}
- 当前用户邮箱: {{.CurrentUser.Email}}
- 当前用户头像: {{.CurrentUser.Profile.Avatar}}索引访问:
- 第一个用户: {{index .Users 0}}
- 第一个用户名: {{(index .Users 0).Name}}
- 第一个产品价格: {{(index .Products 0).Price}}映射访问:
- 主题设置: {{index .Settings "theme"}}
- 语言设置: {{index .Settings "language"}}
- 页面大小: {{index .Settings "page_size"}}
`tmpl := template.Must(template.New("basic").Parse(basicTemplate))fmt.Println("模板内容:")fmt.Println(basicTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, ad.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}// DemoConditionalActions 演示条件Action
func (ad *ActionDemo) DemoConditionalActions() {fmt.Println("=== 条件Action演示 ===\n")conditionalTemplate := `
简单条件判断:
{{if .IsLoggedIn}}
✅ 用户已登录,欢迎 {{.CurrentUser.Name}}!
{{else}}
❌ 用户未登录,请先登录。
{{end}}多重条件判断:
{{if eq .CurrentUser.Role "admin"}}
🔑 管理员权限:可以管理所有功能
{{else if eq .CurrentUser.Role "moderator"}}
🛡️ 版主权限:可以管理内容
{{else}}
👤 普通用户:基础功能访问
{{end}}嵌套条件判断:
{{if .IsLoggedIn}}{{if .CurrentUser.Active}}{{if eq .CurrentUser.Role "admin"}}
🎯 活跃管理员:{{.CurrentUser.Name}}{{else}}
👍 活跃用户:{{.CurrentUser.Name}}{{end}}{{else}}
⚠️ 账户已被禁用{{end}}
{{else}}
🚪 请登录后访问
{{end}}条件与函数结合:
{{if gt .Stats.TotalUsers 0}}
📊 系统统计:
- 总用户数: {{.Stats.TotalUsers}}
- 活跃用户: {{.Stats.ActiveUsers}}
- 活跃率: {{printf "%.1f%%" (div (mul .Stats.ActiveUsers 100.0) .Stats.TotalUsers)}}
{{else}}
📭 暂无用户数据
{{end}}
`// 添加自定义函数funcMap := template.FuncMap{"div": func(a, b float64) float64 { return a / b },"mul": func(a, b float64) float64 { return a * b },}tmpl := template.Must(template.New("conditional").Funcs(funcMap).Parse(conditionalTemplate))fmt.Println("模板内容:")fmt.Println(conditionalTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, ad.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}// DemoRangeActions 演示循环Action
func (ad *ActionDemo) DemoRangeActions() {fmt.Println("=== 循环Action演示 ===\n")rangeTemplate := `
基础循环 - 用户列表:
{{range .Users}}
- ID: {{.ID}}, 姓名: {{.Name}}, 邮箱: {{.Email}}, 状态: {{if .Active}}✅ 活跃{{else}}❌ 禁用{{end}}
{{else}}
📭 暂无用户数据
{{end}}带索引的循环 - 产品列表:
{{range $index, $product := .Products}}
{{add $index 1}}. {{$product.Name}} - ¥{{printf "%.2f" $product.Price}} 分类: {{$product.Category}} | 库存: {{if $product.InStock}}✅ 有货{{else}}❌ 缺货{{end}}评分: {{$product.Rating}}/5.0 ({{$product.ReviewCount}} 评价)
{{else}}
📦 暂无产品数据
{{end}}映射循环 - 系统设置:
{{range $key, $value := .Settings}}
- {{$key}}: {{$value}}
{{end}}嵌套循环 - 分类层级:
{{range .Categories}}
{{if eq .Level 1}}
📁 {{.Name}} (Level {{.Level}}){{range $.Categories}}{{if and .ParentID (eq .ParentID $.ID)}}└── 📄 {{.Name}} (Level {{.Level}}){{end}}{{end}}
{{end}}
{{end}}条件循环 - 活跃用户:
活跃用户列表:
{{range .Users}}
{{if .Active}}
✅ {{.Name}} ({{.Role}}) - 加入时间: {{.JoinedAt.Format "2006-01-02"}}
{{end}}
{{end}}
`// 添加自定义函数funcMap := template.FuncMap{"add": func(a, b int) int { return a + b },"and": func(a, b bool) bool { return a && b },"eq":  func(a, b interface{}) bool { return a == b },}tmpl := template.Must(template.New("range").Funcs(funcMap).Parse(rangeTemplate))fmt.Println("模板内容:")fmt.Println(rangeTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, ad.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}

2. 自定义函数系统

2.1 函数注册与管理

// FunctionRegistry 函数注册表
type FunctionRegistry struct {functions map[string]interface{}metadata  map[string]*FunctionMetadatamutex     sync.RWMutex
}// FunctionMetadata 函数元数据
type FunctionMetadata struct {Name        string   `json:"name"`         // 函数名称Description string   `json:"description"`  // 函数描述Category    string   `json:"category"`     // 函数分类Parameters  []string `json:"parameters"`   // 参数说明ReturnType  string   `json:"return_type"`  // 返回类型Example     string   `json:"example"`      // 使用示例Notes       []string `json:"notes"`        // 注意事项
}// NewFunctionRegistry 创建函数注册表
func NewFunctionRegistry() *FunctionRegistry {registry := &FunctionRegistry{functions: make(map[string]interface{}),metadata:  make(map[string]*FunctionMetadata),}// 注册内置函数registry.registerBuiltinFunctions()return registry
}// registerBuiltinFunctions 注册内置函数
func (fr *FunctionRegistry) registerBuiltinFunctions() {// 字符串处理函数fr.RegisterFunction("upper", strings.ToUpper, &FunctionMetadata{Name:        "upper",Description: "将字符串转换为大写",Category:    "字符串",Parameters:  []string{"str string"},ReturnType:  "string",Example:     `{{"hello" | upper}} => "HELLO"`,Notes:       []string{"支持Unicode字符"},})fr.RegisterFunction("lower", strings.ToLower, &FunctionMetadata{Name:        "lower",Description: "将字符串转换为小写",Category:    "字符串",Parameters:  []string{"str string"},ReturnType:  "string",Example:     `{{"HELLO" | lower}} => "hello"`,Notes:       []string{"支持Unicode字符"},})fr.RegisterFunction("title", strings.Title, &FunctionMetadata{Name:        "title",Description: "将字符串转换为标题格式",Category:    "字符串",Parameters:  []string{"str string"},ReturnType:  "string",Example:     `{{"hello world" | title}} => "Hello World"`,Notes:       []string{"每个单词首字母大写"},})fr.RegisterFunction("trim", strings.TrimSpace, &FunctionMetadata{Name:        "trim",Description: "去除字符串首尾空白字符",Category:    "字符串",Parameters:  []string{"str string"},ReturnType:  "string",Example:     `{{"  hello  " | trim}} => "hello"`,Notes:       []string{"包括空格、制表符、换行符"},})fr.RegisterFunction("contains", strings.Contains, &FunctionMetadata{Name:        "contains",Description: "检查字符串是否包含子字符串",Category:    "字符串",Parameters:  []string{"str string", "substr string"},ReturnType:  "bool",Example:     `{{contains "hello world" "world"}} => true`,Notes:       []string{"区分大小写"},})fr.RegisterFunction("replace", strings.ReplaceAll, &FunctionMetadata{Name:        "replace",Description: "替换字符串中的所有匹配项",Category:    "字符串",Parameters:  []string{"str string", "old string", "new string"},ReturnType:  "string",Example:     `{{replace "hello world" "world" "Go"}} => "hello Go"`,Notes:       []string{"替换所有匹配项"},})fr.RegisterFunction("split", strings.Split, &FunctionMetadata{Name:        "split",Description: "按分隔符分割字符串",Category:    "字符串",Parameters:  []string{"str string", "sep string"},ReturnType:  "[]string",Example:     `{{split "a,b,c" ","}} => ["a", "b", "c"]`,Notes:       []string{"返回字符串切片"},})fr.RegisterFunction("join", strings.Join, &FunctionMetadata{Name:        "join",Description: "用分隔符连接字符串切片",Category:    "字符串",Parameters:  []string{"strs []string", "sep string"},ReturnType:  "string",Example:     `{{join .Tags ", "}} => "tag1, tag2, tag3"`,Notes:       []string{"第一个参数必须是字符串切片"},})// 数学函数fr.RegisterFunction("add", func(a, b interface{}) interface{} {return addNumbers(a, b)}, &FunctionMetadata{Name:        "add",Description: "数字相加",Category:    "数学",Parameters:  []string{"a number", "b number"},ReturnType:  "number",Example:     `{{add 1 2}} => 3`,Notes:       []string{"支持int、float64类型"},})fr.RegisterFunction("sub", func(a, b interface{}) interface{} {return subNumbers(a, b)}, &FunctionMetadata{Name:        "sub",Description: "数字相减",Category:    "数学",Parameters:  []string{"a number", "b number"},ReturnType:  "number",Example:     `{{sub 5 2}} => 3`,Notes:       []string{"支持int、float64类型"},})fr.RegisterFunction("mul", func(a, b interface{}) interface{} {return mulNumbers(a, b)}, &FunctionMetadata{Name:        "mul",Description: "数字相乘",Category:    "数学",Parameters:  []string{"a number", "b number"},ReturnType:  "number",Example:     `{{mul 3 4}} => 12`,Notes:       []string{"支持int、float64类型"},})fr.RegisterFunction("div", func(a, b interface{}) interface{} {return divNumbers(a, b)}, &FunctionMetadata{Name:        "div",Description: "数字相除",Category:    "数学",Parameters:  []string{"a number", "b number"},ReturnType:  "number",Example:     `{{div 10 2}} => 5`,Notes:       []string{"除数不能为0", "返回float64类型"},})fr.RegisterFunction("mod", func(a, b int) int {if b != 0 {return a % b}return 0}, &FunctionMetadata{Name:        "mod",Description: "求模运算",Category:    "数学",Parameters:  []string{"a int", "b int"},ReturnType:  "int",Example:     `{{mod 10 3}} => 1`,Notes:       []string{"除数不能为0"},})// 时间函数fr.RegisterFunction("now", func() string {return time.Now().Format("2006-01-02 15:04:05")}, &FunctionMetadata{Name:        "now",Description: "获取当前时间",Category:    "时间",Parameters:  []string{},ReturnType:  "string",Example:     `{{now}} => "2024-01-15 14:30:25"`,Notes:       []string{"格式:YYYY-MM-DD HH:mm:ss"},})fr.RegisterFunction("formatTime", func(layout, timeStr string) string {t, err := time.Parse("2006-01-02T15:04:05Z", timeStr)if err != nil {return timeStr}return t.Format(layout)}, &FunctionMetadata{Name:        "formatTime",Description: "格式化时间字符串",Category:    "时间",Parameters:  []string{"layout string", "timeStr string"},ReturnType:  "string",Example:     `{{formatTime "2006-01-02" .CreatedAt}} => "2024-01-15"`,Notes:       []string{"使用Go时间格式布局"},})fr.RegisterFunction("timeAgo", func(t time.Time) string {return formatTimeAgo(t)}, &FunctionMetadata{Name:        "timeAgo",Description: "计算时间距离现在的相对时间",Category:    "时间",Parameters:  []string{"t time.Time"},ReturnType:  "string",Example:     `{{timeAgo .CreatedAt}} => "2小时前"`,Notes:       []string{"返回中文相对时间"},})// 工具函数fr.RegisterFunction("default", func(defaultVal, val interface{}) interface{} {if val == nil || val == "" || val == 0 {return defaultVal}return val}, &FunctionMetadata{Name:        "default",Description: "提供默认值",Category:    "工具",Parameters:  []string{"defaultVal interface{}", "val interface{}"},ReturnType:  "interface{}",Example:     `{{default "未知" .Name}} => "未知" (如果Name为空)`,Notes:       []string{"当值为nil、空字符串或0时使用默认值"},})fr.RegisterFunction("safe", func(s string) template.HTML {return template.HTML(s)}, &FunctionMetadata{Name:        "safe",Description: "标记字符串为安全HTML",Category:    "工具",Parameters:  []string{"s string"},ReturnType:  "template.HTML",Example:     `{{safe "<b>粗体</b>"}} => <b>粗体</b>`,Notes:       []string{"跳过HTML转义", "确保内容安全"},})fr.RegisterFunction("json", func(v interface{}) string {return toJSON(v)}, &FunctionMetadata{Name:        "json",Description: "将值转换为JSON字符串",Category:    "工具",Parameters:  []string{"v interface{}"},ReturnType:  "string",Example:     `{{json .User}} => {"id":1,"name":"张三"}`,Notes:       []string{"用于调试或JavaScript交互"},})
}// setupTemplates 设置模板
func (ecs *ECommerceSystem) setupTemplates() {funcMap := ecs.funcRegistry.GetFuncMap()// 产品列表模板productListTemplate := `
=== {{.Site.Name}} - 产品列表 ==={{range .Products}}
📦 {{.Name}}价格: {{formatPrice .Price}}{{if .InStock}}特价: {{formatPrice (applyDiscount .Price 0.1)}}{{end}}评分: {{stars .Rating}} ({{.ReviewCount}}条评价)状态: {{stockStatus .InStock}}分类: {{.Category}}
{{end}}💰 统计信息:
- 商品总数: {{.Analytics.TotalProducts}}
- 平均价格: {{formatPrice .Analytics.AvgOrderValue}}
- 总销售额: {{formatPrice .Analytics.TotalSales}}
`// 订单管理模板orderTemplate := `
=== 订单管理系统 ===📋 订单列表:
{{range .Orders}}
订单 #{{.ID}}:用户ID: {{.UserID}}产品ID: {{.ProductID}}数量: {{.Quantity}}总价: {{formatPrice .TotalPrice}}状态: {{orderStatusStyle .Status}}下单时间: {{.CreatedAt.Format "2006-01-02 15:04:05"}}距今: {{timeAgo .CreatedAt}}
{{end}}📊 订单统计:
- 总订单数: {{.Analytics.TotalOrders}}
- 平均订单金额: {{formatPrice .Analytics.AvgOrderValue}}
- 总销售额: {{formatPrice .Analytics.TotalSales}}
`// 用户评价模板reviewTemplate := `
=== 用户评价系统 ===💬 最新评价:
{{range .Reviews}}
评价 #{{.ID}}:产品ID: {{.ProductID}}用户ID: {{.UserID}}评分: {{stars (float64 .Rating)}}评论: "{{.Comment}}"时间: {{.CreatedAt.Format "2006-01-02 15:04:05"}}距今: {{timeAgo .CreatedAt}}
{{end}}⭐ 评价统计:
{{range .Products}}
- {{.Name}}: {{stars .Rating}} ({{.ReviewCount}}条评价)
{{end}}
`// 促销活动模板promotionTemplate := `
=== 促销活动中心 ===🎉 当前活动:
{{range .Promotions}}
{{if .Active}}
活动: {{.Name}}描述: {{.Description}}折扣: {{printf "%.0f%%" (mul .Discount 100)}}开始: {{.StartDate.Format "2006-01-02"}}结束: {{.EndDate.Format "2006-01-02"}}状态: ✅ 进行中
{{end}}
{{end}}💡 促销示例:
{{range .Products}}
{{if .InStock}}
- {{.Name}}:原价: {{formatPrice .Price}}{{range $.Promotions}}{{if .Active}}{{$.Name}}优惠价: {{formatPrice (applyDiscount $.Price .Discount)}}{{end}}{{end}}
{{end}}
{{end}}
`// 编译模板ecs.templates["products"] = template.Must(template.New("products").Funcs(funcMap).Parse(productListTemplate))ecs.templates["orders"] = template.Must(template.New("orders").Funcs(funcMap).Parse(orderTemplate))ecs.templates["reviews"] = template.Must(template.New("reviews").Funcs(funcMap).Parse(reviewTemplate))ecs.templates["promotions"] = template.Must(template.New("promotions").Funcs(funcMap).Parse(promotionTemplate))
}// RenderProducts 渲染产品列表
func (ecs *ECommerceSystem) RenderProducts() {fmt.Println("=== 产品列表渲染演示 ===\n")if err := ecs.templates["products"].Execute(os.Stdout, ecs.data); err != nil {fmt.Printf("渲染产品模板失败: %v\n", err)}fmt.Println()
}// RenderOrders 渲染订单列表
func (ecs *ECommerceSystem) RenderOrders() {fmt.Println("=== 订单列表渲染演示 ===\n")if err := ecs.templates["orders"].Execute(os.Stdout, ecs.data); err != nil {fmt.Printf("渲染订单模板失败: %v\n", err)}fmt.Println()
}// RenderReviews 渲染评价列表
func (ecs *ECommerceSystem) RenderReviews() {fmt.Println("=== 评价列表渲染演示 ===\n")if err := ecs.templates["reviews"].Execute(os.Stdout, ecs.data); err != nil {fmt.Printf("渲染评价模板失败: %v\n", err)}fmt.Println()
}// RenderPromotions 渲染促销活动
func (ecs *ECommerceSystem) RenderPromotions() {fmt.Println("=== 促销活动渲染演示 ===\n")if err := ecs.templates["promotions"].Execute(os.Stdout, ecs.data); err != nil {fmt.Printf("渲染促销模板失败: %v\n", err)}fmt.Println()
}// DemoComplexPipelines 演示复杂管道操作
func (ecs *ECommerceSystem) DemoComplexPipelines() {fmt.Println("=== 复杂管道操作演示 ===\n")complexTemplate := `
🔄 复杂管道操作示例:产品价格处理管道:
{{range .Products}}
- {{.Name | upper}}:{{.Price | formatPrice | printf "原价: %s"}}{{.Price | applyDiscount 0.2 | formatPrice | printf "8折价: %s"}}{{.Price | applyDiscount 0.3 | formatPrice | printf "7折价: %s"}}{{if .InStock}}{{.Price | applyDiscount 0.15 | formatPrice | printf "会员价: %s"}}{{end}}
{{end}}用户订单统计管道:
{{range .Users}}
- {{.Name | title}}的订单:{{range $.Orders}}{{if eq .UserID $.ID}}订单#{{.ID}}: {{.TotalPrice | formatPrice}} ({{.Status | orderStatusStyle}}){{end}}{{end}}
{{end}}评分与评价管道:
{{range .Products}}
- {{.Name}}:评分显示: {{.Rating | stars}}评分文字: {{.Rating | printf "%.1f分"}}评价统计: {{.ReviewCount | printf "%d条评价"}}综合评价: {{.Rating | printf "%.1f分" | printf "%s,"}}{{.ReviewCount | printf "%d条评价"}}
{{end}}时间处理管道:
{{range .Orders}}
- 订单#{{.ID}}:下单时间: {{.CreatedAt | timeAgo}}格式化时间: {{.CreatedAt.Format "2006-01-02 15:04:05"}}状态显示: {{.Status | orderStatusStyle}}
{{end}}
`funcMap := ecs.funcRegistry.GetFuncMap()tmpl := template.Must(template.New("complex").Funcs(funcMap).Parse(complexTemplate))if err := tmpl.Execute(os.Stdout, ecs.data); err != nil {fmt.Printf("执行复杂管道模板失败: %v\n", err)}fmt.Println()
}## 5. 主函数演示```go
// main 主函数演示
func main() {fmt.Println("🚀 Go模板Action、函数与管道系统演示")fmt.Println("=" * 50)// 1. Action注册表演示fmt.Println("\n📋 第一部分:Action系统演示")actionRegistry := NewActionRegistry()actionRegistry.PrintActionGuide()// 2. Action演示actionDemo := NewActionDemo()actionDemo.DemoVariableActions()actionDemo.DemoConditionalActions()actionDemo.DemoRangeActions()// 3. 函数注册表演示fmt.Println("\n🔧 第二部分:自定义函数演示")functionRegistry := NewFunctionRegistry()functionRegistry.PrintFunctionGuide()// 4. 函数演示functionDemo := NewFunctionDemo()functionDemo.DemoStringFunctions()functionDemo.DemoMathFunctions()functionDemo.DemoTimeFunctions()// 5. 管道操作演示fmt.Println("\n🔄 第三部分:管道操作演示")pipelineDemo := NewPipelineDemo()pipelineDemo.DemoPipelineBasics()pipelineDemo.DemoAdvancedPipelines()// 6. 电商系统综合演示fmt.Println("\n🛒 第四部分:电商系统综合演示")ecommerceSystem := NewECommerceSystem()// 渲染各个模块ecommerceSystem.RenderProducts()ecommerceSystem.RenderOrders()ecommerceSystem.RenderReviews()ecommerceSystem.RenderPromotions()// 复杂管道演示ecommerceSystem.DemoComplexPipelines()fmt.Println("\n✅ 演示完成!")fmt.Println("\n📚 本章学习要点:")fmt.Println("1. 掌握了Go模板的8种核心Action操作")fmt.Println("2. 学会了自定义函数的注册和使用")fmt.Println("3. 理解了管道操作的链式处理机制")fmt.Println("4. 通过电商系统实战项目综合应用所有特性")fmt.Println("5. 掌握了模板的高级数据处理和格式化技巧")
}// 辅助函数:重复字符串
func repeatString(s string, count int) string {result := ""for i := 0; i < count; i++ {result += s}return result
}

6. 最佳实践与性能优化

6.1 Action使用最佳实践

// ActionBestPractices Action最佳实践指南
type ActionBestPractices struct{}// 1. 变量Action最佳实践
func (abp *ActionBestPractices) VariableActionTips() {fmt.Println("=== 变量Action最佳实践 ===")fmt.Println("✅ 推荐做法:")fmt.Println("  • 使用有意义的变量名")fmt.Println("  • 避免过深的嵌套访问")fmt.Println("  • 使用with简化深层访问")fmt.Println("  • 为可能为nil的字段提供默认值")fmt.Println("\n❌ 避免做法:")fmt.Println("  • 不要在模板中进行复杂计算")fmt.Println("  • 避免在循环中重复访问相同数据")fmt.Println("  • 不要忽略nil值检查")
}// 2. 条件Action最佳实践
func (abp *ActionBestPractices) ConditionalActionTips() {fmt.Println("=== 条件Action最佳实践 ===")fmt.Println("✅ 推荐做法:")fmt.Println("  • 使用简单的布尔表达式")fmt.Println("  • 合理使用else if减少嵌套")fmt.Println("  • 将复杂逻辑移到Go代码中")fmt.Println("  • 使用自定义函数简化条件判断")fmt.Println("\n❌ 避免做法:")fmt.Println("  • 避免过度嵌套的条件语句")fmt.Println("  • 不要在条件中进行副作用操作")fmt.Println("  • 避免复杂的逻辑运算")
}// 3. 循环Action最佳实践
func (abp *ActionBestPractices) RangeActionTips() {fmt.Println("=== 循环Action最佳实践 ===")fmt.Println("✅ 推荐做法:")fmt.Println("  • 为空集合提供else分支")fmt.Println("  • 使用索引变量进行编号")fmt.Println("  • 在循环外预处理数据")fmt.Println("  • 限制循环次数避免性能问题")fmt.Println("\n❌ 避免做法:")fmt.Println("  • 避免在循环中进行复杂计算")fmt.Println("  • 不要在循环中调用外部服务")fmt.Println("  • 避免过深的嵌套循环")
}

6.2 函数设计最佳实践

// FunctionBestPractices 函数最佳实践指南
type FunctionBestPractices struct{}// 函数设计原则
func (fbp *FunctionBestPractices) FunctionDesignPrinciples() {fmt.Println("=== 函数设计最佳实践 ===")fmt.Println("🎯 设计原则:")fmt.Println("  1. 单一职责:每个函数只做一件事")fmt.Println("  2. 纯函数:无副作用,相同输入产生相同输出")fmt.Println("  3. 类型安全:进行参数类型检查")fmt.Println("  4. 错误处理:优雅处理异常情况")fmt.Println("  5. 性能优化:避免重复计算")fmt.Println("\n📝 命名规范:")fmt.Println("  • 使用动词开头的函数名")fmt.Println("  • 保持名称简洁明了")fmt.Println("  • 遵循Go命名约定")fmt.Println("  • 提供清晰的文档说明")
}// 性能优化技巧
func (fbp *FunctionBestPractices) PerformanceOptimization() {fmt.Println("=== 性能优化技巧 ===")fmt.Println("⚡ 优化策略:")fmt.Println("  1. 缓存计算结果")fmt.Println("  2. 避免重复的类型转换")fmt.Println("  3. 使用字符串构建器")fmt.Println("  4. 预分配切片容量")fmt.Println("  5. 减少内存分配")fmt.Println("\n🔍 性能监控:")fmt.Println("  • 使用基准测试")fmt.Println("  • 监控内存使用")fmt.Println("  • 分析CPU性能")fmt.Println("  • 记录执行时间")
}

6.3 管道操作最佳实践

// PipelineBestPractices 管道最佳实践指南
type PipelineBestPractices struct{}// 管道设计原则
func (pbp *PipelineBestPractices) PipelineDesignPrinciples() {fmt.Println("=== 管道操作最佳实践 ===")fmt.Println("🔗 设计原则:")fmt.Println("  1. 链式调用:保持数据流的连续性")fmt.Println("  2. 类型一致:确保管道中的类型兼容")fmt.Println("  3. 错误处理:在管道中优雅处理错误")fmt.Println("  4. 可读性:保持管道的可读性")fmt.Println("  5. 性能考虑:避免不必要的中间转换")fmt.Println("\n💡 使用技巧:")fmt.Println("  • 将复杂管道分解为多个步骤")fmt.Println("  • 使用括号明确优先级")fmt.Println("  • 为管道添加注释说明")fmt.Println("  • 测试管道的边界情况")
}

7. 章节总结

本章深入探讨了Go模板系统的三大核心特性:Action动作系统、自定义函数和管道操作。通过系统性的学习和实战演练,我们掌握了模板的高级应用技巧。

7.1 核心内容回顾

Action动作系统

  • 掌握了8种核心Action类型及其使用场景
  • 学会了变量输出、条件判断、循环遍历等基础操作
  • 理解了上下文切换、模板调用等高级特性
  • 通过ActionRegistry实现了Action的统一管理

自定义函数系统

  • 建立了完整的函数注册和管理机制
  • 实现了字符串、数学、时间、工具等多类别函数
  • 学会了函数元数据管理和文档生成
  • 掌握了类型安全和错误处理的最佳实践

管道操作系统

  • 理解了管道的链式处理机制
  • 学会了基础管道和高级管道操作
  • 掌握了数据过滤、排序、聚合等高级技巧
  • 实现了复杂的数据转换和格式化

7.2 技术特色

模块化设计:每个组件都采用了清晰的接口设计,便于扩展和维护。

丰富的中文注释:所有代码都包含详细的中文注释,便于理解和学习。

最佳实践指导:提供了完整的最佳实践指南,避免常见陷阱。

完整的错误处理:实现了健壮的错误处理机制,确保系统稳定性。

性能优化考虑:在设计中充分考虑了性能因素,提供了优化建议。

7.3 实际应用价值

模板开发:为Web应用、报告生成、邮件模板等提供了强大的模板处理能力。

数据展示:通过丰富的函数和管道操作,可以灵活地格式化和展示数据。

业务逻辑:将复杂的业务逻辑封装为自定义函数,提高模板的可维护性。

系统集成:提供了标准化的模板处理接口,便于与其他系统集成。

7.4 下一章预告

下一章我们将学习 “Go Web 编程快速入门 · 07.4 - 模板(4):组合模板与逻辑控制”,内容包括:

  • 模板继承机制:实现模板的层次化组织
  • 模板嵌套与组合:构建复杂的模板结构
  • 逻辑控制系统:高级的条件和循环控制
  • 模板缓存优化:提升模板处理性能
  • 实战项目:构建一个完整的CMS内容管理系统

通过下一章的学习,我们将完全掌握Go模板系统的所有高级特性,为构建复杂的Web应用打下坚实基础。

// 数学运算辅助函数
func addNumbers(a, b interface{}) interface{} {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)

switch av.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Int() + bv.Int()case reflect.Float32, reflect.Float64:return float64(av.Int()) + bv.Float()}
case reflect.Float32, reflect.Float64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Float() + float64(bv.Int())case reflect.Float32, reflect.Float64:return av.Float() + bv.Float()}
}
return 0

}

func subNumbers(a, b interface{}) interface{} {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)

switch av.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Int() - bv.Int()case reflect.Float32, reflect.Float64:return float64(av.Int()) - bv.Float()}
case reflect.Float32, reflect.Float64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Float() - float64(bv.Int())case reflect.Float32, reflect.Float64:return av.Float() - bv.Float()}
}
return 0

}

func mulNumbers(a, b interface{}) interface{} {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)

switch av.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Int() * bv.Int()case reflect.Float32, reflect.Float64:return float64(av.Int()) * bv.Float()}
case reflect.Float32, reflect.Float64:switch bv.Kind() {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return av.Float() * float64(bv.Int())case reflect.Float32, reflect.Float64:return av.Float() * bv.Float()}
}
return 0

}

func divNumbers(a, b interface{}) interface{} {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)

var aFloat, bFloat float64switch av.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:aFloat = float64(av.Int())
case reflect.Float32, reflect.Float64:aFloat = av.Float()
default:return 0
}switch bv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:bFloat = float64(bv.Int())
case reflect.Float32, reflect.Float64:bFloat = bv.Float()
default:return 0
}if bFloat != 0 {return aFloat / bFloat
}
return 0

}

// formatTimeAgo 格式化相对时间
func formatTimeAgo(t time.Time) string {
duration := time.Since(t)

if duration < time.Minute {return "刚刚"
} else if duration < time.Hour {minutes := int(duration.Minutes())return fmt.Sprintf("%d分钟前", minutes)
} else if duration < 24*time.Hour {hours := int(duration.Hours())return fmt.Sprintf("%d小时前", hours)
} else if duration < 30*24*time.Hour {days := int(duration.Hours() / 24)return fmt.Sprintf("%d天前", days)
} else if duration < 365*24*time.Hour {months := int(duration.Hours() / (24 * 30))return fmt.Sprintf("%d个月前", months)
} else {years := int(duration.Hours() / (24 * 365))return fmt.Sprintf("%d年前", years)
}

}

// toJSON 转换为JSON字符串
func toJSON(v interface{}) string {
data, err := json.Marshal(v)
if err != nil {
return fmt.Sprintf(“JSON转换错误: %v”, err)
}
return string(data)
}

// RegisterFunction 注册函数
func (fr *FunctionRegistry) RegisterFunction(name string, fn interface{}, metadata *FunctionMetadata) {
fr.mutex.Lock()
defer fr.mutex.Unlock()

fr.functions[name] = fn
fr.metadata[name] = metadatafmt.Printf("✅ 注册函数: %s (%s)\n", name, metadata.Description)

}

// GetFuncMap 获取函数映射
func (fr *FunctionRegistry) GetFuncMap() template.FuncMap {
fr.mutex.RLock()
defer fr.mutex.RUnlock()

funcMap := make(template.FuncMap)
for name, fn := range fr.functions {funcMap[name] = fn
}
return funcMap

}

// GetFunctionMetadata 获取函数元数据
func (fr *FunctionRegistry) GetFunctionMetadata(name string) *FunctionMetadata {
fr.mutex.RLock()
defer fr.mutex.RUnlock()
return fr.metadata[name]
}

// ListFunctions 列出所有函数
func (fr *FunctionRegistry) ListFunctions() map[string]*FunctionMetadata {
fr.mutex.RLock()
defer fr.mutex.RUnlock()

result := make(map[string]*FunctionMetadata)
for name, metadata := range fr.metadata {result[name] = metadata
}
return result

}

// PrintFunctionGuide 打印函数使用指南
func (fr *FunctionRegistry) PrintFunctionGuide() {
fmt.Println(“=== Go模板自定义函数使用指南 ===\n”)

functions := fr.ListFunctions()
categories := make(map[string][]*FunctionMetadata)// 按分类组织函数
for _, metadata := range functions {categories[metadata.Category] = append(categories[metadata.Category], metadata)
}// 按分类打印
for category, funcs := range categories {fmt.Printf("📂 %s函数:\n", category)for _, fn := range funcs {fmt.Printf("  • %s: %s\n", fn.Name, fn.Description)fmt.Printf("    参数: %s\n", strings.Join(fn.Parameters, ", "))fmt.Printf("    返回: %s\n", fn.ReturnType)fmt.Printf("    示例: %s\n", fn.Example)if len(fn.Notes) > 0 {fmt.Printf("    注意: %s\n", strings.Join(fn.Notes, "; "))}fmt.Println()}
}

}


### 2.2 函数使用演示```go
// FunctionDemo 函数演示器
type FunctionDemo struct {registry *FunctionRegistrydata     *ActionDemoData
}// NewFunctionDemo 创建函数演示器
func NewFunctionDemo() *FunctionDemo {return &FunctionDemo{registry: NewFunctionRegistry(),data:     createDemoData(),}
}// DemoStringFunctions 演示字符串函数
func (fd *FunctionDemo) DemoStringFunctions() {fmt.Println("=== 字符串函数演示 ===\n")stringTemplate := `
字符串转换函数:
- 原始: "{{.CurrentUser.Name}}"
- 大写: "{{.CurrentUser.Name | upper}}"
- 小写: "{{.CurrentUser.Name | lower}}"
- 标题: "{{.CurrentUser.Profile.Bio | title}}"
- 去空格: "{{trim "  Go语言  "}}"字符串检查函数:
- 包含检查: {{if contains .CurrentUser.Email "@"}}✅ 有效邮箱{{else}}❌ 无效邮箱{{end}}
- 替换操作: "{{replace .CurrentUser.Profile.Bio "管理员" "超级管理员"}}"字符串分割与连接:
- 分割邮箱: {{split .CurrentUser.Email "@"}}
- 连接示例: {{join (split .CurrentUser.Email "@") " [AT] "}}默认值处理:
- 网站: {{default "暂无网站" .CurrentUser.Profile.Website}}
- 位置: {{default "未知位置" .CurrentUser.Profile.Location}}
`tmpl := template.Must(template.New("string").Funcs(fd.registry.GetFuncMap()).Parse(stringTemplate))fmt.Println("模板内容:")fmt.Println(stringTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, fd.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}// DemoMathFunctions 演示数学函数
func (fd *FunctionDemo) DemoMathFunctions() {fmt.Println("=== 数学函数演示 ===\n")mathTemplate := `
基础数学运算:
- 加法: {{add 10 5}} = 15
- 减法: {{sub 10 5}} = 5
- 乘法: {{mul 10 5}} = 50
- 除法: {{div 10 5}} = 2
- 取模: {{mod 10 3}} = 1实际数据计算:
- 用户总数: {{.Stats.TotalUsers}}
- 活跃用户: {{.Stats.ActiveUsers}}
- 非活跃用户: {{sub .Stats.TotalUsers .Stats.ActiveUsers}}
- 活跃率: {{printf "%.1f%%" (mul (div .Stats.ActiveUsers .Stats.TotalUsers) 100)}}产品价格计算:
{{range .Products}}
- {{.Name}}: 原价: ¥{{printf "%.2f" .Price}}折扣价(8折): ¥{{printf "%.2f" (mul .Price 0.8)}}税后价格(含6%税): ¥{{printf "%.2f" (mul .Price 1.06)}}
{{end}}统计计算:
- 产品平均价格: ¥{{printf "%.2f" (div (add (add (index .Products 0).Price (index .Products 1).Price) (index .Products 2).Price) 3)}}
- 总评价数: {{add (add (index .Products 0).ReviewCount (index .Products 1).ReviewCount) (index .Products 2).ReviewCount}}
`tmpl := template.Must(template.New("math").Funcs(fd.registry.GetFuncMap()).Parse(mathTemplate))fmt.Println("模板内容:")fmt.Println(mathTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, fd.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}// DemoTimeFunctions 演示时间函数
func (fd *FunctionDemo) DemoTimeFunctions() {fmt.Println("=== 时间函数演示 ===\n")timeTemplate := `
当前时间:
- 完整时间: {{now}}
- 当前年份: {{formatTime "2006" (now)}}
- 当前月份: {{formatTime "01" (now)}}用户加入时间:
{{range .Users}}
- {{.Name}}:加入时间: {{.JoinedAt.Format "2006-01-02 15:04:05"}}格式化: {{formatTime "2006年01月02日" (.JoinedAt.Format "2006-01-02T15:04:05Z")}}相对时间: {{timeAgo .JoinedAt}}加入天数: {{printf "%.0f" (.JoinedAt.Sub (timeAgo .JoinedAt)).Hours | div 24}}天
{{end}}时间比较:
{{range .Users}}
{{if .JoinedAt.Before (now.Add (mul -7 24 time.Hour))}}
- {{.Name}} 是老用户 (加入超过7天)
{{else}}
- {{.Name}} 是新用户 (加入不到7天)
{{end}}
{{end}}
`// 添加时间相关的自定义函数customFuncMap := fd.registry.GetFuncMap()customFuncMap["timeAgo"] = func(t time.Time) string {return formatTimeAgo(t)}tmpl := template.Must(template.New("time").Funcs(customFuncMap).Parse(timeTemplate))fmt.Println("模板内容:")fmt.Println(timeTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, fd.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}

3. 管道操作系统

3.1 管道基础与链式操作

// PipelineDemo 管道演示器
type PipelineDemo struct {registry *FunctionRegistrydata     *ActionDemoData
}// NewPipelineDemo 创建管道演示器
func NewPipelineDemo() *PipelineDemo {return &PipelineDemo{registry: NewFunctionRegistry(),data:     createDemoData(),}
}// DemoPipelineBasics 演示管道基础
func (pd *PipelineDemo) DemoPipelineBasics() {fmt.Println("=== 管道操作基础演示 ===\n")pipelineTemplate := `
基础管道操作:
- 简单管道: {{"hello world" | upper}} 
- 链式管道: {{"  HELLO WORLD  " | trim | lower | title}}
- 数值管道: {{10 | add 5 | mul 2 | sub 3}}字符串处理管道:
{{range .Users}}
- 用户: {{.Name | upper}} 
- 邮箱域名: {{.Email | split "@" | index . 1 | upper}}
- 角色显示: {{.Role | title | printf "【%s】"}}
- 状态: {{if .Active}}{{"✅ 活跃" | upper}}{{else}}{{"❌ 禁用" | upper}}{{end}}
{{end}}复杂数据处理管道:
{{range .Products}}
- 产品: {{.Name | title}}
- 价格: {{.Price | printf "¥%.2f" | printf "原价: %s"}}
- 折扣价: {{.Price | mul 0.8 | printf "¥%.2f" | printf "折扣价: %s"}}
- 分类: {{.Category | upper | printf "[%s]"}}
- 评分: {{.Rating | printf "%.1f/5.0" | printf "评分: %s"}}
{{end}}条件管道:
{{range .Users}}
- {{.Name}}: {{if .Active}}{{.Role | title | printf "%s (活跃)"}}{{else}}{{.Role | title | printf "%s (禁用)"}}{{end}}
{{end}}嵌套管道:
- 活跃用户数: {{.Stats.ActiveUsers | printf "%d个"}}
- 活跃率: {{.Stats.ActiveUsers | div .Stats.TotalUsers | mul 100 | printf "%.1f%%"}}
- 用户增长: {{.Stats.TotalUsers | sub .Stats.ActiveUsers | printf "还需激活%d个用户"}}
`tmpl := template.Must(template.New("pipeline").Funcs(pd.registry.GetFuncMap()).Parse(pipelineTemplate))fmt.Println("模板内容:")fmt.Println(pipelineTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, pd.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}// DemoAdvancedPipelines 演示高级管道操作
func (pd *PipelineDemo) DemoAdvancedPipelines() {fmt.Println("=== 高级管道操作演示 ===\n")// 注册高级管道函数advancedFuncMap := pd.registry.GetFuncMap()// 数组过滤函数advancedFuncMap["filter"] = func(items []User, condition string) []User {var result []Userfor _, item := range items {switch condition {case "active":if item.Active {result = append(result, item)}case "admin":if item.Role == "admin" {result = append(result, item)}}}return result}// 数组映射函数advancedFuncMap["map"] = func(items []User, field string) []string {var result []stringfor _, item := range items {switch field {case "name":result = append(result, item.Name)case "email":result = append(result, item.Email)case "role":result = append(result, item.Role)}}return result}// 数组排序函数advancedFuncMap["sortBy"] = func(items []Product, field string) []Product {result := make([]Product, len(items))copy(result, items)switch field {case "price":// 简化排序实现for i := 0; i < len(result)-1; i++ {for j := i + 1; j < len(result); j++ {if result[i].Price > result[j].Price {result[i], result[j] = result[j], result[i]}}}case "rating":for i := 0; i < len(result)-1; i++ {for j := i + 1; j < len(result); j++ {if result[i].Rating < result[j].Rating {result[i], result[j] = result[j], result[i]}}}}return result}// 聚合函数advancedFuncMap["sum"] = func(items []Product, field string) float64 {var sum float64for _, item := range items {switch field {case "price":sum += item.Pricecase "rating":sum += item.Rating}}return sum}advancedFuncMap["avg"] = func(items []Product, field string) float64 {if len(items) == 0 {return 0}sum := advancedFuncMap["sum"].(func([]Product, string) float64)(items, field)return sum / float64(len(items))}advancedTemplate := `
高级管道操作:数组过滤管道:
- 活跃用户: {{.Users | filter "active" | map "name" | join ", "}}
- 管理员: {{.Users | filter "admin" | map "name" | join ", "}}数组排序管道:
按价格排序的产品:
{{range .Products | sortBy "price"}}
- {{.Name}}: ¥{{.Price | printf "%.2f"}}
{{end}}按评分排序的产品:
{{range .Products | sortBy "rating"}}
- {{.Name}}: {{.Rating | printf "%.1f"}}⭐
{{end}}聚合计算管道:
- 产品总价值: ¥{{.Products | sum "price" | printf "%.2f"}}
- 平均价格: ¥{{.Products | avg "price" | printf "%.2f"}}
- 平均评分: {{.Products | avg "rating" | printf "%.1f"}}⭐复合管道操作:
- 活跃用户邮箱域名: {{.Users | filter "active" | map "email" | join ", " | split ", " | join " | " | upper}}
- 产品名称汇总: {{.Products | sortBy "rating" | map "name" | join " → " | printf "推荐顺序: %s"}}条件管道链:
{{range .Products}}
- {{.Name}}: {{if .InStock}}{{.Price | mul 0.9 | printf "¥%.2f (9折优惠)"}}{{else}}{{.Price | printf "¥%.2f (缺货)"}}{{end}}
{{end}}数据转换管道:
{{range .Users}}
- {{.Name | printf "用户: %s" | upper}} | {{.Email | split "@" | index . 1 | printf "域名: %s" | upper}} | {{.JoinedAt | timeAgo | printf "加入: %s"}}
{{end}}
`tmpl := template.Must(template.New("advanced").Funcs(advancedFuncMap).Parse(advancedTemplate))fmt.Println("模板内容:")fmt.Println(advancedTemplate)fmt.Println("渲染结果:")if err := tmpl.Execute(os.Stdout, pd.data); err != nil {fmt.Printf("执行模板失败: %v\n", err)}fmt.Println()
}

4. 综合实战项目:电商产品展示系统

4.1 项目数据模型

// ECommerceData 电商数据
type ECommerceData struct {Site        SiteInfo    `json:"site"`Products    []Product   `json:"products"`Categories  []Category  `json:"categories"`Users       []User      `json:"users"`Orders      []Order     `json:"orders"`Reviews     []Review    `json:"reviews"`Promotions  []Promotion `json:"promotions"`Analytics   Analytics   `json:"analytics"`
}// SiteInfo 站点信息
type SiteInfo struct {Name        string `json:"name"`Logo        string `json:"logo"`Description string `json:"description"`Currency    string `json:"currency"`Language    string `json:"language"`Timezone    string `json:"timezone"`
}// Order 订单
type Order struct {ID          int       `json:"id"`UserID      int       `json:"user_id"`ProductID   int       `json:"product_id"`Quantity    int       `json:"quantity"`TotalPrice  float64   `json:"total_price"`Status      string    `json:"status"`CreatedAt   time.Time `json:"created_at"`ShippedAt   *time.Time `json:"shipped_at"`
}// Review 评价
type Review struct {ID        int       `json:"id"`ProductID int       `json:"product_id"`UserID    int       `json:"user_id"`Rating    int       `json:"rating"`Comment   string    `json:"comment"`CreatedAt time.Time `json:"created_at"`
}// Promotion 促销
type Promotion struct {ID          int       `json:"id"`Name        string    `json:"name"`Description string    `json:"description"`Discount    float64   `json:"discount"`StartDate   time.Time `json:"start_date"`EndDate     time.Time `json:"end_date"`Active      bool      `json:"active"`
}// Analytics 分析数据
type Analytics struct {TotalSales    float64 `json:"total_sales"`TotalOrders   int     `json:"total_orders"`TotalProducts int     `json:"total_products"`TotalUsers    int     `json:"total_users"`AvgOrderValue float64 `json:"avg_order_value"`TopProducts   []int   `json:"top_products"`
}// ECommerceSystem 电商系统
type ECommerceSystem struct {data         *ECommerceDatafuncRegistry *FunctionRegistrytemplates    map[string]*template.Template
}// NewECommerceSystem 创建电商系统
func NewECommerceSystem() *ECommerceSystem {system := &ECommerceSystem{data:         createECommerceData(),funcRegistry: NewFunctionRegistry(),templates:    make(map[string]*template.Template),}// 注册电商专用函数system.registerECommerceFunctions()// 设置模板system.setupTemplates()return system
}// createECommerceData 创建电商演示数据
func createECommerceData() *ECommerceData {// 创建产品数据products := []Product{{ID: 1, Name: "Go语言编程指南", Price: 89.99, Category: "技术书籍",InStock: true, Rating: 4.8, ReviewCount: 156,},{ID: 2, Name: "云原生架构实战", Price: 99.99, Category: "技术书籍",InStock: true, Rating: 4.9, ReviewCount: 234,},{ID: 3, Name: "微服务设计模式", Price: 79.99, Category: "技术书籍",InStock: false, Rating: 4.7, ReviewCount: 89,},{ID: 4, Name: "Docker容器技术", Price: 69.99, Category: "技术书籍",InStock: true, Rating: 4.6, ReviewCount: 123,},{ID: 5, Name: "Kubernetes实战", Price: 109.99, Category: "技术书籍",InStock: true, Rating: 4.9, ReviewCount: 198,},}// 创建订单数据orders := []Order{{ID: 1, UserID: 1, ProductID: 1, Quantity: 2, TotalPrice: 179.98, Status: "已发货", CreatedAt: time.Now().Add(-48 * time.Hour)},{ID: 2, UserID: 2, ProductID: 2, Quantity: 1, TotalPrice: 99.99, Status: "处理中", CreatedAt: time.Now().Add(-24 * time.Hour)},{ID: 3, UserID: 1, ProductID: 4, Quantity: 1, TotalPrice: 69.99, Status: "已完成", CreatedAt: time.Now().Add(-72 * time.Hour)},}// 创建评价数据reviews := []Review{{ID: 1, ProductID: 1, UserID: 1, Rating: 5, Comment: "非常好的Go语言教程,内容详实", CreatedAt: time.Now().Add(-24 * time.Hour)},{ID: 2, ProductID: 2, UserID: 2, Rating: 5, Comment: "云原生架构讲解很清晰", CreatedAt: time.Now().Add(-48 * time.Hour)},{ID: 3, ProductID: 1, UserID: 3, Rating: 4, Comment: "适合初学者,推荐", CreatedAt: time.Now().Add(-72 * time.Hour)},}// 创建促销数据promotions := []Promotion{{ID: 1, Name: "新年特惠", Description: "全场技术书籍8折优惠",Discount: 0.2, StartDate: time.Now().Add(-7 * 24 * time.Hour),EndDate: time.Now().Add(7 * 24 * time.Hour), Active: true,},{ID: 2, Name: "会员专享", Description: "VIP用户额外9折",Discount: 0.1, StartDate: time.Now().Add(-30 * 24 * time.Hour),EndDate: time.Now().Add(30 * 24 * time.Hour), Active: true,},}return &ECommerceData{Site: SiteInfo{Name: "技术书城", Logo: "/logo.png", Description: "专业的技术图书在线商城",Currency: "CNY", Language: "zh-CN", Timezone: "Asia/Shanghai",},Products:   products,Categories: []Category{{ID: 1, Name: "技术书籍", ParentID: nil, Level: 1}},Users:      createDemoData().Users,Orders:     orders,Reviews:    reviews,Promotions: promotions,Analytics: Analytics{TotalSales: 349.96, TotalOrders: 3, TotalProducts: 5, TotalUsers: 3,AvgOrderValue: 116.65, TopProducts: []int{1, 2, 4},},}
}// registerECommerceFunctions 注册电商专用函数
func (ecs *ECommerceSystem) registerECommerceFunctions() {funcMap := ecs.funcRegistry.GetFuncMap()// 价格格式化函数ecs.funcRegistry.RegisterFunction("formatPrice", func(price float64) string {return fmt.Sprintf("¥%.2f", price)}, &FunctionMetadata{Name: "formatPrice", Description: "格式化价格显示",Category: "电商", Parameters: []string{"price float64"},ReturnType: "string", Example: `{{formatPrice 99.99}} => "¥99.99"`,})// 折扣计算函数ecs.funcRegistry.RegisterFunction("applyDiscount", func(price, discount float64) float64 {return price * (1 - discount)}, &FunctionMetadata{Name: "applyDiscount", Description: "应用折扣计算",Category: "电商", Parameters: []string{"price float64", "discount float64"},ReturnType: "float64", Example: `{{applyDiscount 100 0.2}} => 80`,})// 评分星级显示函数ecs.funcRegistry.RegisterFunction("stars", func(rating float64) string {fullStars := int(rating)halfStar := rating-float64(fullStars) >= 0.5result := strings.Repeat("⭐", fullStars)if halfStar {result += "⭐"}return result}, &FunctionMetadata{Name: "stars", Description: "显示星级评分",Category: "电商", Parameters: []string{"rating float64"},ReturnType: "string", Example: `{{stars 4.5}} => "⭐⭐⭐⭐⭐"`,})// 库存状态函数ecs.funcRegistry.RegisterFunction("stockStatus", func(inStock bool) string {if inStock {return "✅ 现货"}return "❌ 缺货"}, &FunctionMetadata{Name: "stockStatus", Description: "显示库存状态",Category: "电商", Parameters: []string{"inStock bool"},ReturnType: "string", Example: `{{stockStatus true}} => "✅ 现货"`,})// 订单状态样式函数ecs.funcRegistry.RegisterFunction("orderStatusStyle", func(status string) string {switch status {case "已完成":return "✅ " + statuscase "已发货":return "🚚 " + statuscase "处理中":return "⏳ " + statuscase "已取消":return "❌ " + statusdefault:return "📋 " + status}}, &FunctionMetadata{Name: "orderStatusStyle", Description: "订单状态样式化显示",Category: "电商", Parameters: []string{"status string"},ReturnType: "string", Example: `{{orderStatusStyle "已发货"}} => "🚚 已发货"`,})
}
http://www.dtcms.com/a/529187.html

相关文章:

  • 专业的培训行业网站制作北京网站建设一条龙
  • Spring Bean定义继承:配置复用的高效技巧
  • 湖北网站建设专家本地搭建linux服务器做网站
  • 龙华建网站百度账号官网
  • Python高效爬虫:使用twisted构建异步网络爬虫详解
  • 做爰片的网站公司企业网络宣传设计方案
  • 基于鸿蒙UniProton的PLC控制系统开发指南
  • 建设部网站查询造价师证件地方门户网站的前途
  • 【案例实战】HarmonyOS SDK新体验:利用近场能力打造无缝的跨设备文件传输功能
  • AI边缘设备时钟设计突围:从ppm级稳定到EMC优化的全链路实践
  • typescript—元组类型介绍
  • 限元方法进行电磁-热耦合模拟
  • 三维网站搭建教程直播网站app开发
  • 品牌网站建设 优帮云在百度上做个网站多少合适
  • 无聊。切个水题。
  • 公司微信网站制作wordpress插件汉化教程视频
  • 海东营销网站建设公司福州seo关键词
  • 松江 企业网站建设怎么样做移动油光文字网站
  • 无法生成dump——MiniDumpWriteDump 阻塞原因分析
  • 如何在1v1一对一视频直播交友APP中实现防录屏防截屏功能?
  • 网站做新闻外链有作用吗营销导向的网站建设的主要流程
  • C++笔记(面向对象)对于对象返回方式的讲解
  • CMP(类ClouderaCDP7.3(404次编译) )完全支持华为鲲鹏Aarch64(ARM)POC报告
  • 网站后台管理系统破解网站建设目标规划
  • 在本地生活赛道,如何打造属于自己的业务护城河?
  • 云南省建设厅网站查询企业oa办公软件
  • 网站如何做搜狗搜索引擎合肥网红打卡地
  • PPIO上线DeepSeek-OCR模型
  • AtCoder Beginner Contest 426 题解
  • 服务器 网站 app网络技术员工作内容