当前位置: 代码网 > it编程>前端脚本>Golang > Golang Template实现自定义函数的操作指南

Golang Template实现自定义函数的操作指南

2025年02月13日 Golang 我要评论
1. 基础用法1.1 创建简单模板函数package mainimport ( "html/template" "os")func main() { // 创建自定义函数映射

1. 基础用法

1.1 创建简单模板函数

package main

import (
    "html/template"
    "os"
)

func main() {
    // 创建自定义函数映射
    funcmap := template.funcmap{
        "upper": strings.toupper,
        "lower": strings.tolower,
    }
    
    // 创建模板并添加函数
    tmpl := template.new("test").funcs(funcmap)
    
    // 解析模板内容
    tmpl, err := tmpl.parse(`
        原始字符串: {{.}}
        大写: {{upper .}}
        小写: {{lower .}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    // 执行模板
    err = tmpl.execute(os.stdout, "hello, world!")
}

1.2 带参数的模板函数

package main

import (
    "html/template"
    "os"
)

func main() {
    funcmap := template.funcmap{
        "add": func(a, b int) int {
            return a + b
        },
        "multiply": func(a, b int) int {
            return a * b
        },
    }
    
    tmpl := template.new("calc").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        {{add 5 3}} = 8
        {{multiply 4 6}} = 24
    `)
    
    if err != nil {
        panic(err)
    }
    
    err = tmpl.execute(os.stdout, nil)
}

2. 高级用法

2.1 条件判断函数

package main

import (
    "html/template"
    "os"
)

func main() {
    funcmap := template.funcmap{
        "iseven": func(n int) bool {
            return n%2 == 0
        },
        "ifthenelse": func(condition bool, a, b interface{}) interface{} {
            if condition {
                return a
            }
            return b
        },
    }
    
    tmpl := template.new("conditions").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        {{range $i := .}}
            数字 {{$i}} 是: {{if iseven $i}}偶数{{else}}奇数{{end}}
            另一种写法: {{ifthenelse (iseven $i) "偶数" "奇数"}}
        {{end}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    numbers := []int{1, 2, 3, 4, 5}
    err = tmpl.execute(os.stdout, numbers)
}

2.2 格式化函数

package main

import (
    "fmt"
    "html/template"
    "os"
    "time"
)

func main() {
    funcmap := template.funcmap{
        "formatdate": func(t time.time) string {
            return t.format("2006-01-02 15:04:05")
        },
        "formatprice": func(price float64) string {
            return fmt.sprintf("¥%.2f", price)
        },
    }
    
    tmpl := template.new("format").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        当前时间: {{formatdate .time}}
        商品价格: {{formatprice .price}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    data := struct {
        time  time.time
        price float64
    }{
        time:  time.now(),
        price: 99.99,
    }
    
    err = tmpl.execute(os.stdout, data)
}

2.3 切片操作函数

package main

import (
    "html/template"
    "os"
)

func main() {
    funcmap := template.funcmap{
        "first": func(x []interface{}) interface{} {
            if len(x) > 0 {
                return x[0]
            }
            return nil
        },
        "last": func(x []interface{}) interface{} {
            if len(x) > 0 {
                return x[len(x)-1]
            }
            return nil
        },
        "slice": func(x []interface{}, start, end int) []interface{} {
            if start < 0 {
                start = 0
            }
            if end > len(x) {
                end = len(x)
            }
            return x[start:end]
        },
    }
    
    tmpl := template.new("slice").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        完整切片: {{.}}
        第一个元素: {{first .}}
        最后一个元素: {{last .}}
        切片[1:3]: {{slice . 1 3}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    data := []interface{}{1, 2, 3, 4, 5}
    err = tmpl.execute(os.stdout, data)
}

3. 实用示例

3.1 html 安全转义

package main

import (
    "html/template"
    "os"
)

func main() {
    funcmap := template.funcmap{
        "safe": func(s string) template.html {
            return template.html(s)
        },
        "safeattr": func(s string) template.htmlattr {
            return template.htmlattr(s)
        },
    }
    
    tmpl := template.new("safe").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        普通文本: {{.text}}
        html内容: {{safe .html}}
        属性值: <div {{safeattr .attr}}></div>
    `)
    
    if err != nil {
        panic(err)
    }
    
    data := struct {
        text string
        html string
        attr string
    }{
        text: "<b>文本</b>",
        html: "<b>html</b>",
        attr: `style="color: red"`,
    }
    
    err = tmpl.execute(os.stdout, data)
}

3.2 数据过滤和转换

package main

import (
    "html/template"
    "os"
    "strings"
)

func main() {
    funcmap := template.funcmap{
        "join": strings.join,
        "split": strings.split,
        "title": strings.title,
        "filter": func(arr []string, f func(string) bool) []string {
            var result []string
            for _, v := range arr {
                if f(v) {
                    result = append(result, v)
                }
            }
            return result
        },
    }
    
    tmpl := template.new("filter").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        原始数组: {{.}}
        join结果: {{join . ","}}
        split结果: {{split "a,b,c" ","}}
        title结果: {{title "hello world"}}
        filter结果: {{filter . (lambda "len" "gt" 3)}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    data := []string{"apple", "banana", "orange", "pear"}
    err = tmpl.execute(os.stdout, data)
}

4. 最佳实践

4.1 模板函数组织

// template_funcs.go
package template

import "html/template"

// 创建全局函数映射
var globalfuncmap = template.funcmap{
    // 字符串操作
    "upper":      strings.toupper,
    "lower":      strings.tolower,
    "title":      strings.title,
    
    // 数值操作
    "add":        func(a, b int) int { return a + b },
    "subtract":   func(a, b int) int { return a - b },
    "multiply":   func(a, b int) int { return a * b },
    "divide":     func(a, b int) float64 { return float64(a) / float64(b) },
    
    // 日期操作
    "formatdate": func(t time.time, layout string) string { return t.format(layout) },
    "now":        time.now,
    
    // 切片操作
    "first":      first,
    "last":       last,
    "slice":      slice,
    
    // 条件操作
    "iseven":     iseven,
    "ifthenelse": ifthenelse,
}

// 在应用中使用
func main() {
    tmpl := template.new("page").funcs(globalfuncmap)
    // ... 其他操作
}

4.2 错误处理

package main

import (
    "html/template"
    "os"
)

func main() {
    funcmap := template.funcmap{
        "divide": func(a, b int) (string, error) {
            if b == 0 {
                return "", fmt.errorf("除数不能为零")
            }
            return fmt.sprintf("%.2f", float64(a)/float64(b)), nil
        },
    }
    
    tmpl := template.new("error").funcs(funcmap)
    tmpl, err := tmpl.parse(`
        {{with $result := divide 10 2}}
            结果: {{$result}}
        {{else}}
            计算出错
        {{end}}
    `)
    
    if err != nil {
        panic(err)
    }
    
    err = tmpl.execute(os.stdout, nil)
}

总结

1.基本原则

  • 保持函数简单明确
  • 注意类型安全
  • 适当处理错误
  • 避免过度复杂的逻辑

2.常见用途

  • 文本格式化
  • 数据转换
  • 条件判断
  • 集合操作
  • html 安全处理

3.性能考虑

  • 缓存模板
  • 避免重复解析
  • 合理使用内存

到此这篇关于golang template实现自定义函数的操作指南的文章就介绍到这了,更多相关go template自定义函数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com