Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go Template自定义函数

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

作者:老大白菜

这篇文章主要为大家详细介绍了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.常见用途

3.性能考虑

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

您可能感兴趣的文章:
阅读全文