Go 模板语法详解

发布时间:2026/9/19 3:27:46

Go 模板语法详解 个人主页会编程的土豆欢迎来访作者简介后端学习者❄️个人专栏数据结构与算法数据库leetcode✨那些你一个人走过的夜路终将化作照亮未来的光目标吃透{{ }}里的动作action输出、变量、条件、循环、with、管道与内置函数。这是后面嵌套/继承/Gin 的语法基础。1. 模板语法总览Go 模板里普通文本原样输出逻辑都写在action中{{ ... }}常见类别类别例子作用输出{{.Name}}打印值注释{{/* ... */}}不输出变量{{$x : .}}绑定到$x条件{{if}}...{{end}}分支循环{{range}}...{{end}}遍历改上下文{{with}}...{{end}}临时切换.管道{{. | printf %s}}函数链式处理模板调用{{template x .}}嵌套下节细讲2. 点dot.当前上下文.是模板里最重要的概念Execute(w, data)时根上下文.data进入range/with后.可能变成「当前元素」离开range/with后.恢复例子type Product struct { Name string Price int } type Page struct { ShopName string Items []Product }店铺{{.ShopName}} {{range .Items}} !-- 这里的 . 是 Product -- 商品{{.Name}}价格{{.Price}} {{end}} !-- 这里 . 又回到 Page -- 再次显示店铺{{.ShopName}}如果在range里还想访问外层的ShopName不能写{{.ShopName}}因为.已是 Product要用变量把外层存起来3. 输出与注释3.1 输出字段 / 键 / 方法{{.Name}} !-- struct 导出字段 -- {{.User.Email}} !-- 链式字段 -- {{index .Map k}} !-- map 取值的稳妥写法 -- {{.FullName}} !-- 无参方法方法名需导出 --方法示例type User struct { First string Last string } func (u User) FullName() string { return u.First u.Last }{{.FullName}}注意方法若返回(value, error)模板执行时若 error ! nil 会失败3.2 注释{{/* 这是注释不会出现在最终 HTML 里 */}}注释不能嵌套内容里也不要随便写*/}}这类结束符3.3 什么时候会「空输出」访问不到的字段、nil 指针的字段等在默认设置下可能输出为空或在missingkey等选项下报错。调试时建议先把数据结构打印出来确认字段名大小写一致4. 变量$name用$定义模板变量{{$title : .Title}} h1{{$title}}/h1为什么需要变量最经典场景range 里访问外层数据{{$shop : .ShopName}} {{range .Items}} li{{$shop}} - {{.Name}}/li {{end}}也可以在range时直接接收索引和元素{{range $i, $item : .Items}} li#{{$i}} {{$item.Name}}/li {{end}}赋值与重新绑定{{$x : 1}} {{$x 2}} !-- 重新赋值Go 1.11 模板支持 --入门更常见的是:定义一次后只读使用作用域变量一般在定义它的{{if}}/{{range}}/{{with}}/...{{end}}块内有效在块外可能不可见以你使用的 Go 版本与定义位置为准。实践建议在需要的最小范围内定义。5. 条件if/else/else if{{if .LoggedIn}} p欢迎{{.Name}}/p {{else}} p请先登录/p {{end}}什么算「真」模板把下列值视为false不进入if主体false数字0空字符串nil空的 array / slice / map / chan其它一般视为 true。多分支{{if eq .Role admin}} 管理员面板 {{else if eq .Role editor}} 编辑面板 {{else}} 普通用户 {{end}}比较函数很常用这些是内置函数不是操作符写成函数含义eqne!ltlegtge{{if gt .Age 18}} 成年 {{end}} {{if eq .Status ok ready}} !-- eq 支持多参数与任一相等即为真 -- 可用 {{end}}逻辑与或非{{if and .A .B}} ... {{end}} {{if or .A .B}} ... {{end}} {{if not .Hidden}} ... {{end}}6.with临时切换上下文with有两个作用判断值是否为真若为真在块内把.换成这个值{{with .Profile}} p城市{{.City}}/p p签名{{.Bio}}/p {{else}} p用户未填写资料/p {{end}}等价心智模型如果 Profile 有值 进入块且 . Profile 否则 走 elsewith 变量{{with $p : .Profile}} {{$p.City}} {{end}}ifvswithifwith是否切换.否是适合纯条件判断深入嵌套结构体字段很多人写{{if .Profile}}{{.Profile.City}}{{end}}用with更干净。7.range遍历可遍历slice、array、map、channel。7.1 基础遍历ul {{range .Items}} li{{.Name}} - ¥{{.Price}}/li {{else}} li暂无商品/li {{end}} /ulelse分支在集合为空时执行非常适合空状态 UI。7.2 索引与元素{{range $index, $product : .Items}} tr td{{$index}}/td td{{$product.Name}}/td /tr {{end}}遍历 map{{range $key, $value : .Labels}} span{{$key}}{{$value}}/span {{end}}注意map 的遍历顺序不稳定随机若要稳定展示应在 Go 里先排好序再传给模板或传[]struct{Key, Value}。7.3 range 里修改了.{{range .Items}} !-- . 是元素 -- {{.Name}} {{end}}若只写{{range .Items}}不接变量元素就绑定到.。8. 管道pipeline管道用|把左边结果作为右边函数的最后一个参数。{{.Name | printf 用户%s}}等价于printf(用户%s, .Name)。多级管道{{.Name | printf %s | html}}在html/template中上下文感知转义通常已自动发生这里主要演示管道形态。常见内置函数函数作用例子printf格式化{{printf %.2f .Price}}len长度{{len .Items}}index下标/键访问{{index .Items 0}}slice切片新版本支持{{slice .Items 0 3}}and/or/not逻辑见上urlquery查询参数转义{{.Q | urlquery}}js/html等按上下文转义较少手写index详解{{index .Scores 0}} !-- slice[0] -- {{index .UserMap u100}} !-- map[u100] -- {{index .Matrix 1 2}} !-- 多维先 [1] 再 [2] --当字段名是动态字符串、或键不是合法标识符时index很有用。printf详解{{printf %s-%d .Name .Age}} {{.Price | printf %d}}9. 综合示例商品列表页main.go数据package main import ( html/template os ) type Product struct { Name string Price int Tags []string } type Page struct { Title string ShopName string VIP bool Items []Product } func main() { tmpl : template.Must(template.New(list).Parse(listHTML)) data : Page{ Title: 今日特价, ShopName: 七米小店, VIP: true, Items: []Product{ {Name: Go 书, Price: 88, Tags: []string{编程, 热销}}, {Name: 键盘, Price: 299, Tags: []string{外设}}, }, } tmpl.Execute(os.Stdout, data) } const listHTML !DOCTYPE html html headmeta charsetutf-8title{{.Title}}/title/head body h1{{.Title}}/h1 p店铺{{.ShopName}}/p {{if .VIP}} pVIP 专属折扣已开启/p {{else}} p开通 VIP 更优惠/p {{end}} p共 {{len .Items}} 件商品/p {{$shop : .ShopName}} ul {{range $i, $p : .Items}} li #{{$i}} [{{$shop}}] strong{{$p.Name}}/strong {{printf %d $p.Price}} {{with $p.Tags}} 标签 {{range .}} span{{.}}/span {{end}} {{end}} /li {{else}} li暂无商品/li {{end}} /ul {{with index .Items 0}} p推荐{{.Name}}/p {{end}} /body /html 这个例子一口气用到了输出、if、len$shop保留外层range带索引with处理标签printf管道式格式化index取第一件商品建议你改数据把Items置空、把VIP改false观察分支变化。10. 空值与安全输出意识指针字段type User struct { Name *string }若Name nil{{.Name}}可能出问题或为空。更稳妥是在 Go 侧先规范化数据或模板里{{with .Name}}{{.}}{{else}}匿名{{end}}HTML 转义html/template会按插入点上下文转义。用户可控内容不要随便用template.HTML关闭转义lesson08 会讲。缺失键对 map可设置tmpl.Option(missingkeyerror)让访问不存在的 key 直接报错便于调试
延伸阅读

更多相关文章

2026/9/16 18:52:02

Grove TDS传感器原理、校准与物联网应用实战指南

1. 项目缘起:从“水质”到“可测”的最后一公里 做水质监测项目,无论是家庭净水器滤芯寿命提醒、鱼缸水质管理,还是小型农业灌溉、水培营养液监控,TDS(总溶解固体)都是一个绕不开的核心指标。它虽然不能告诉…

2026/9/16 18:51:59

抖音爆款内容自动分发机器人是如何炼成的?——扣子平台API深度调用与合规风控全拆解(2024最新版)

更多请点击: https://codechina.net 第一章:抖音爆款内容自动分发机器人的核心价值与合规边界 抖音爆款内容自动分发机器人并非简单的内容搬运工具,而是融合算法理解、平台规则适配与用户行为建模的智能协同系统。其核心价值体现在三重维度&…

2026/9/19 3:23:22

智慧校园双中台架构:服务中台与数据中台全拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 3:23:22

国产FPGA实战:基于PGL50H的千兆网口RGMII与UDP通信开发记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 3:23:22

Qt 5.14.2在aarch64上的静态交叉编译完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 3:23:22

UE5运行时FBX导入:FBX SDK与ProceduralMeshComponent实战解析

1. 先交代背景:为什么一个“导入模型”功能要自己写去年在数字孪生项目里被一个需求卡了好几天:要在UE5项目里实现运行时动态导入FBX模型,用户点一个按钮就能把本地FBX放进场景,而不是像传统做法那样在编辑器里导入。当时第一反应…

2026/9/19 3:23:22

基于uniapp+PHP的社区团购小程序开发实战

1. 系统整体设计与技术选型思路1.1 为什么是uniapp PHP的组合社区团购这个业务,前端要覆盖微信小程序、H5、甚至后续可能的App端,后端要快速上线、方便维护。我最终选定的是uniapp做前端、PHP(ThinkPHP框架)做后端服务、微信小程…

2026/9/19 3:18:22

Cursor接入Claude官方API与Claude Code:从补全工具到AI编程搭档

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码