
go 标准模板(`text/template`/`html/template`)不内置除法操作符,需通过 `funcmap` 注册自定义函数(如 `divide`)来安全执行整数除法,并在模板中调用。
go 模板语言设计简洁,仅支持有限的内置操作(如 +, -, *, eq, and, or 等),但不支持 / 除法运算符。因此,像 {{if .Id/2}} 这样的写法会编译失败(unexpected “/” in if)。要实现除法逻辑,必须将计算逻辑移出模板,通过自定义函数注入。
✅ 正确做法:注册 divide 自定义函数
使用 template.Funcs() 方法向模板注册一个函数映射(FuncMap),例如:
fm := template.FuncMap{ "divide": func(a, b int) int { if b == 0 { panic("division by zero") } return a / b }, }
⚠️ 注意:实际生产环境建议返回 float64 或增加错误处理(如返回 (int, Error)),但因 Go 模板不支持多值返回或 error 类型,此处采用 panic + 日志或前置校验更稳妥。
? 完整可运行示例
package main import ( "os" "text/template" ) func main() { // 定义 divide 函数:整数除法(需确保 b ≠ 0) fm := template.FuncMap{ "divide": func(a, b int) int { if b == 0 { panic("template: divide by zero") } return a / b }, } // 模板字符串:支持条件判断与数值计算 tmplTxt := `{{if (eq (divide .Id 2) 5)}} HEY, I CAN DO IT! (.Id is 10) {{else}} WHY??? (divide result = {{divide .Id 2}}) {{end}}` tmpl, err := template.New("example").Funcs(fm).Parse(tmplTxt) if err != nil { panic(err) } // 渲染数据:Id = 10 → 10/2 = 5 → 条件为 true data := struct{ Id int }{Id: 10} err = tmpl.Execute(os.Stdout, data) if err != nil { panic(err) } }
输出结果:
HEY, I CAN DO IT! (.Id is 10)
? 关键要点总结
- ❌ {{.Id/2}} 语法非法,Go 模板不解析数学运算符 /;
- ✅ 必须通过 FuncMap 显式注册函数(如 “divide”),并在模板中以函数调用形式使用:{{divide .Id 2}};
- ✅ 支持嵌套调用,如 {{eq (divide .Id 2) 5}},用于条件判断;
- ⚠️ 除零需主动防御(模板内无法 recover panic,建议在业务层确保输入安全);
- ? 若需浮点除法,可定义 divf 函数返回 float64,并配合 printf “%.2f” 格式化输出。
通过这一机制,你既能保持模板的声明式表达力,又能灵活扩展所需逻辑——这是 Go 模板“逻辑最小化、行为可扩展”设计理念的典型实践。