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

 更新时间:2025年02月07日 09:33:43   作者:老大白菜  
这篇文章主要为大家详细介绍了Golang如何利用Template实现自定义函数的操作,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下

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自定义函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang实现读取excel文件并转换为JSON格式

    Golang实现读取excel文件并转换为JSON格式

    本文介绍了如何使用Golang读取Excel文件并将其转换为JSON格式,通过安装excelize依赖和创建readExcelToJSON方法,可以实现这一功能,如果需要转换数据类型,可以修改相应的代码,需要的朋友可以参考下
    2025-03-03
  • golang连接MongoDB数据库及数据库操作指南

    golang连接MongoDB数据库及数据库操作指南

    MongoDB是Nosql中常用的一种数据库,下面这篇文章主要给大家介绍了关于golang连接MongoDB数据库及数据库操作的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • 详解Go语言中的内存对齐

    详解Go语言中的内存对齐

    前面我们学习了Go语言空结构体详解,最近又在看unsafe包的知识,在查阅相关资料时不免会看到内存对齐相关的内容。虽然不会,但可以学呀,那么这篇文章,我们就一起来看下什么是内存对齐吧
    2022-10-10
  • GoFrame框架gset交差并补集使用实例

    GoFrame框架gset交差并补集使用实例

    这篇文章主要为大家介绍了GoFrame框架gset交差并补集使用实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go Println和Printf的区别详解

    Go Println和Printf的区别详解

    这篇文章主要介绍了Go Println和Printf的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go语言中的并发goroutine底层原理

    Go语言中的并发goroutine底层原理

    这篇文章主要介绍了Go语言中的并发goroutine底层原理,介绍Go语言并发底层原理,以及对比Go语言并发与其他语言并发的优劣,下文详细内容,需要的小伙伴可以参考一下
    2022-02-02
  • Golang工作池的使用实例讲解

    Golang工作池的使用实例讲解

    我们使用Go语言开发项目,常常会使用到goroutine;goroutine太多会造成系统占用过高或其他系统异常,我们可以将goroutine控制指定数量,且减少goroutine的创建,这就运用到Go工作池,下面就介绍和使用一下
    2023-02-02
  • 深入解析快速排序算法的原理及其Go语言版实现

    深入解析快速排序算法的原理及其Go语言版实现

    这篇文章主要介绍了快速排序算法的原理及其Go语言版实现,文中对于快速算法的过程和效率有较为详细的说明,需要的朋友可以参考下
    2016-04-04
  • 一文教你如何在Golang中用好泛型

    一文教你如何在Golang中用好泛型

    golang的泛型已经出来了一年多了,从提案被接受开始我就在关注泛型了,好用是好用,但问题也很多,所以本文就来教大家如何在Golang中用好泛型吧
    2023-07-07
  • Go压缩位图库roaring安装使用详解

    Go压缩位图库roaring安装使用详解

    这篇文章主要为大家介绍了Go压缩位图库roaring安装使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07

最新评论