
go 的 text/template 包不支持直接使用 `==` 等运算符进行字段比较,而需借助内置函数(如 `eq`)完成逻辑判断;本文详解其用法、原理及常见陷阱。
Go 标准库中的 text/template 包设计遵循“简洁、安全、专注渲染”的原则,因此刻意移除了模板内原生的中缀比较运算符(如 ==, !=, )。取而代之的是提供一组可组合的内置函数(如 eq, ne, lt, gt, and, or, not),所有逻辑判断必须通过函数调用方式表达。
例如,以下写法是错误的(会触发模板解析错误:function "==" not defined):
tpl := `{{if .Brand == "Coke"}}It's a coke{{else}}It's something else{{end}}`✅ 正确写法是使用内置函数 eq(equal):
package main
import (
"os"
"text/template"
)
type Something struct {
Brand string
}
func main() {
data := Something{Brand: "Coke"}
tpl := `{{if eq .Brand "Coke"}}It's a coke{{else}}It's something else{{end}}`
t := template.Must(template.New("test").Parse(tpl))
t.Execute(os.Stdout, data) // 输出:It's a coke
}? eq 函数支持多参数比较(类似 reflect.DeepEqual 的语义),例如 {{if eq .A .B .C}} 表示三者是否全等;但最常用的是二元比较:eq .Field "value"。
其他常用比较函数包括:
- ne:不等于({{if ne .Status "active"}})
- lt / le / gt / ge:小于/小于等于/大于/大于等于(仅适用于数字或可比较类型)
- and, or, not:用于组合条件(注意:and 和 or 是短路求值)
⚠️ 注意事项:
- 字符串字面量必须用双引号 "(单引号 ' 会被视为 rune 字面量,导致类型不匹配);
- 字段访问路径(如 .User.Profile.Name)必须确保每级非 nil,否则运行时 panic;建议配合 with 或 if 安全判空;
- 所有函数调用均无副作用,不可修改数据,仅用于计算与判断。
总结:text/template 的表达能力足够应对绝大多数模板逻辑需求,关键在于转变思维——用函数式风格替代运算符风格。掌握 eq, ne, and, or 等内置函数,再结合 range, with, template 等动作,即可构建清晰、健壮、易维护的模板逻辑。










