tplate

golang template 库使用教程

By Hubert Chen at 2025/10/28

Updated on 2026/05/19

这个文章目前是用来查看各种关键字和函数如何使用的,需要的话可以看看 golang template 库入门教程 文章

文章里的描述可能与实际有出入,请参考官方文档 text/template - Go Packages

在我写 tplate 时,我发现网上能找到的 golang template 教程都很分散,不是很方便,于是打算写一篇文章留给自己用

运算符

逻辑运算符

关键字 使用方法 等价 go 语句
and and C1 C2 C1 && C2
or or C1 C2 C1 || C2
not not C1 !C1

比较运算符

关键字 使用方法 等价 go 语句 备注
eq eq C1 C2 C1 == C2 EQual
ne ne C1 C2 C1 != C2 Not Equal
lt lt C1 C2 C1 < C2 Less Than
le le C1 C2 C1 <= C2 Less than or Equal
gt gt C1 C2 C1 > C2 Greater Than
ge ge C1 C2 C1 >= C2 Greater than or Equal

eq 关键字可以接受多个参数,例如 eq C1 C2 C3,但等价的 go 语句其实是 C1 == C2 || C1 == C3

复杂条件式

如果要创建复杂的条件式,有时需要使用括号 () 将子条件包裹起来

条件式 等价 go 语句
and C1 (not C2) C1 && !C2
and (and (gt C1 1) (gt C2 1)) (ne C1 C2) (C1 > 1 && C2 > 1) && C1 != C2
eq C1 C2 C3 C4 C1 == C2 || C1 == C3 || C1 == C4

关键字

if else 条件判断

可以在模板中判断一些条件,来控制要执行的数据

{{ if .A }}
  {{/* 符合 .A 条件时的内容 */}}
{{ else if .B }}
  {{/* 不符合 .A 但符合 .B 条件时的内容 */}}
{{ else }}
  {{/* 不符合以上全部条件时的内容 */}}
{{ end }}

range 遍历

使用 range 方法即可遍历数组、切片或 map 键值对,也可以在要遍历的对象为空时进行其他操作

{{ range .Slice }}
  {{/* 此时 . 会指向循环中的数据 */}}
  当前遍历的值: {{ . }}
{{ else }}
  这个切片是空的
{{ end }}

在遍历中使用外部值

range 方法的作用域中,. 符号会指向当前遍历的数据,若要在循环中使用外部的值,需要添加 $ 前缀

{{/* 假设传入的数据中有 Slice 和 Value 这两个变量 */}}
这是 Value 的值: {{ .Value }}
{{ range .Slice }}
  当前遍历的值: {{ . }}
  循环外部的值: {{ $.Value }}
{{ end }}

获取索引或键名

在使用 range 方法时可以通过创建变量来获取数组、切片或 map 键值对的索引或键

{{ range $index, $data := .Slice }}
  index 变量:  {{ $index }}
  data 变量:   {{ $data }}
  当前遍历的值: {{ . }}
{{ end }}

创建了变量后依然可以通过 . 来直接调用当前遍历的数据

index 获取单个元素

可以使用 index 方法来获取数组、切片或 map 键值对中的单个元素

{{ $item_0_in_slice := index .Slice 0 }}
切片中的第 0 个元素为 {{ $item_0_in_slice }}
{{ $item_abc_in_map := index .Map "abc" }}
map 键对值中的 abc 元素为 {{ $item_abc_in_map }}

break continue 控制循环

在使用 range 方法遍历内容时,可以像 go 代码的 for 循环一样使用 breakcontinue 控制接下来的操作

{{/* 假设 .Numbers 中的数据是 1,2,3,4,5,6,7,8,9,10 */}}
{{ range .Numbers }}
  {{ if lt . 5 }}
    数字小于 5: {{ . }}
    {{ continue }}
  {{ end }}
  {{ if gt . 2 }}
    正在退出循环
    {{ break }}
  {{ end }}
{{ end }}
现在在循环外

with 暂时修改 . 指向的数据

有时候只需要使用数据中的某个字段,可以用 with 命令来暂时修改 . 指向的数据

{{/* 假设传入的数据结构为 .Post.Date */}}
现在是 {{ .Post.Date.Year }}  {{ .Post.Date.Month }}  {{ .Post.Date.Day }} 
{{ with .Post.Date }}
  {{/* 此时 . 已经指向 .Post.Date,调用 .Year 同等于 .Post.Date.Year */}}
  现在是 {{ .Year }}  {{ .Month }}  {{ .Day }} 
{{ end }}

若要在 with 作用域中使用其他外部值,参考 在遍历中使用外部值

with 命令还可以像 if else 那样选择要使用的数据

{{ with .Update.Date }}
  {{/* 此时 . 指向 .Update.Date */}}
  更新时间 {{ .Year }}  {{ .Month }}  {{ .Day }} 
{{ else with .Create.Date }}
  {{/* 此时 . 指向 .Create.Date */}}
  创建时间 {{ .Year }}  {{ .Month }}  {{ .Day }} 
{{ else }}
  {{/* 因为没有匹配上面的条件,此时 . 没有发生变化 */}}
  未知时间
{{ end }}

define template 定义和调用模板

可以使用 define 命令来预先定义一个模板,再通过 template 命令来调用之前定义的模板

{{ define "A" }}
  {{/* 模板 A 中的 . 为调用时传入的数据 */}}
  在模板 A 中的数据是 {{ . }}
{{ end }}

正在调用模板 A 并传入 "text"
{{ template "A" "text" }}

block 重新定义模板并立即调用

block 命令其实是一个语法糖,它会定义一个模板并立即调用它

{{/* 首先定义一个名为 template 的模板,它会输出传入的数据 */}}
{{ define "template" }}
  传入的数据为 {{ . }}
{{ end }}

{{/* 重新定义 template 模板并传入 . 来执行,它会先输出数据再接着提示语句 */}}
{{ block "template" . }}
  {{ . }} 是传入的数据
{{ end }}
{{/* 同等于下方的代码,但需要注意:在一个模板中不允许定义另一个模板 */}}

{{ define "template" }}
  {{ . }} 是传入的数据
{{ end }}
{{/* 调用重新定义后的 template 模板并传入 . 来执行*/}}
{{ template "template" . }}

为了方便替换使用,go 的 text/templatehtml/template 库中的模板是允许重复定义的,实际的模板为最后被解析的那个

# go # tmpl # 教程