Go go-i18n 怎样向消息模板传入命名字段
Go go-i18n 通过 i18n.LocalizeConfig.TemplateData 向消息模板传入命名字段。数据可以是 map,也可以是包含导出字段的结构体;模板用 {{.User}} 这样的表达式读取对应值。字段名必须与模板约定一致,不能把 JSON 标签名自动当成模板字段名。
官方地址:https://github.com/nicksnyder/go-i18n
选择模板数据而非字符串拼接
一个“文件已就绪”通知要包含用户、文件名和工作区。若在业务代码里先拼出前半句、再追加文件名,翻译人员就难以调整不同语言的语序。把整句作为一个消息模板,再传入命名字段,能让中文与英文各自安排字段位置。
这里的目标是稳定的消息数据契约。MessageID 标识消息,TemplateData 提供本次业务值,模板负责语言表达。命名字段适合需要多语言调整语序的句子;不应把普通数据值反过来拼入模板源码。
使用 TemplateData 传入命名字段
下面把两种语言的消息直接加入 Bundle,省去文件加载,让示例聚焦字段绑定。两条消息共享 UploadReady,字段均为 User、File、Workspace。Localizer 选择语言,Localize 执行对应模板。
package main
import (
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
i18ntemplate "github.com/nicksnyder/go-i18n/v2/i18n/template"
"golang.org/x/text/language"
)
func render() error {
bundle := i18n.NewBundle(language.English)
// 英文和简体中文使用相同消息 ID 与字段名,可分别调整字段顺序。
if err := bundle.AddMessages(language.English, &i18n.Message{
ID: "UploadReady",
Other: "{{.User}}: {{.File}} is ready in {{.Workspace}}.",
}); err != nil {
return err
}
if err := bundle.AddMessages(language.SimplifiedChinese, &i18n.Message{
ID: "UploadReady",
Other: "{{.User}},{{.Workspace}}中的文件{{.File}}已就绪。",
}); err != nil {
return err
}
localizer := i18n.NewLocalizer(bundle, "zh-Hans")
message, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "UploadReady",
TemplateData: map[string]any{
"User": "林岚", "File": "report.csv", "Workspace": "项目资料",
},
// 缺失 map 键时返回模板错误,而不是依赖默认缺键显示。
TemplateParser: &i18ntemplate.TextParser{Option: "missingkey=error"},
})
if err != nil {
return fmt.Errorf("生成文件就绪提示: %w", err)
}
fmt.Println(message)
return nil
}
func main() {
if err := render(); err != nil {
panic(err) // 示例入口停止使用错误或不完整的消息。
}
}
按这段消息文本与字段值,中文提示应包含“林岚”“项目资料”和“report.csv”,它们的位置由中文模板决定。本文未运行程序,不把这段预期描述当作真实输出截图。

TemplateData 只负责执行时的数据,不负责把消息添加到 Bundle。消息不存在、语言发生回退或模板执行失败时,都应处理 Localize 返回的 error,不能只看是否得到非空字符串。接口定义见LocalizeConfig 官方文档。
比较 map 与结构体的数据契约
| 数据形式 | 模板读取 | 适合场景 | 主要注意点 |
|---|---|---|---|
| map[string]any | {{.User}} | 少量灵活字段 | 键名拼错通常只能在运行时发现 |
| 导出字段结构体 | {{.User}} | 消息字段稳定、多个调用点复用 | 字段需导出,模板引用仍是运行时约定 |
| 字符串拼接 | 不提供命名数据 | 仅非常简单且无需翻译重排的文本 | 跨语言语序容易被业务代码锁死 |
例如定义含 User、File、Workspace 三个导出字符串字段的结构体,作为 TemplateData 传入后可沿用同一模板。小写 user 属于未导出字段,不能按导出字段方式读取;json:"user" 不会把 {{.User}} 自动变成 {{.user}}。标准模板按自身字段和键访问规则执行,见text/template 文档。
结构体可以约束 Go 调用方的数据形状,但模板文本中的字段名并不由 Go 编译器检查。消息字段改名时,所有语言模板和数据构造点应一起更新。不要将一个语言中的 User 改为 Username,而其他翻译仍保留旧字段。
把 PluralCount 与显示字段分开
PluralCount 决定使用哪种复数形式,TemplateData 则提供要展示的字段。如果模板需要 {{.Count}},可以在 TemplateData 中明确放入 Count,同时把同一个业务数量传给 PluralCount。不要以为配置了 PluralCount 就一定会向你已经提供的 map 自动追加 Count。

当前实现只有在 TemplateData 为 nil 且 PluralCount 非 nil 时,才会构造包含键 PluralCount 的默认数据。因此此时模板使用的是 {{.PluralCount}};显式传入自己的数据后,需要自行保证模板所需字段齐全。相关行为见Localizer 实现。
这两项职责也不能互相替代:只给显示用的 Count 字段,不会自动触发正确的复数形式选择。数量用来选择语言规则时应保持原始数值语义;若需要特殊显示格式,可另提供展示字段。
处理模板错误及输出边界
默认模板解析器使用 text/template,缺少 map 键的默认选项是 missingkey=default。示例显式使用 TextParser{Option:"missingkey=error"},使 {{.User}} 这类直接字段访问缺键时报告错误。不要把默认缺键表现当作业务回退机制;结构体访问不存在字段也需要正确处理执行错误。
在正常请求处理中通常更适合 Localize 并显式处理错误;MustLocalize 遇错会 panic。业务可记录 MessageID 和缺失字段类别,再按既定策略提供提示,不应在日志中输出用户隐私字段的全部内容。
TemplateData 中的字符串会再次当模板执行吗?普通插入值不是新的模板源码。不要为了二次替换而把用户输入接回模板文本。
生成结果可以直接作为 HTML 吗?默认 text/template 不提供 html/template 的上下文自动转义。将结果放入网页时,应在展示层按上下文转义,不要随意转换为可信 HTML;也不要以为命名字段会自动过滤所有标签。
多个请求能共用一张可变 map 吗?不要让并发请求修改同一个模板数据 map。为每次调用准备独立数据或使用明确的同步与不可变约定,避免请求字段串用。
什么时候选结构体?当同一消息的数据由多个调用点构造、字段长期稳定时,可用小型专用结构体表达契约;字段少且变化较灵活时,map 更直接。无论哪种形式,字段名、错误处理和输出转义都要清楚。
Go jsonschema 接收的 Go 数值类型为什么影响 JSON 校验
- 上一篇
- Go jsonschema 接收的 Go 数值类型为什么影响 JSON 校验
- 下一篇
- Go go-i18n 的 MessageID 与 DefaultMessage 有什么区别
-
- Golang · Go教程 | 22分钟前 |
- Go Hamba Avro 怎样使用读者 Schema 读取演进后的记录
- 330浏览 收藏
-
- Golang · Go教程 | 28分钟前 |
- Go go-vcard 怎样设置优先使用的邮箱字段
- 466浏览 收藏
-
- Golang · Go教程 | 30分钟前 |
- Go go-smtp 怎样重置未完成的发送事务
- 178浏览 收藏
-
- Golang · Go教程 | 35分钟前 |
- Go go-message 怎样同时写入纯文本正文和附件
- 434浏览 收藏
-
- Golang · Go教程 | 37分钟前 |
- Go go-imap 怎样把本地邮件追加到指定邮箱
- 240浏览 收藏
-
- Golang · Go教程 | 43分钟前 |
- Go Paho MQTT Go 怎样在重连回调中恢复业务订阅
- 263浏览 收藏
-
- Golang · Go教程 | 46分钟前 |
- Go JetStream Go 客户端怎样监听键值桶变化
- 173浏览 收藏
-
- Golang · Go教程 | 51分钟前 |
- Go NATS Go 客户端怎样为消息附加请求头
- 149浏览 收藏
-
- Golang · Go教程 | 52分钟前 | go · Go 文本差异 go-diff diffmatchpatch
- Go go-diff 怎样按行压缩文本后计算差异
- 479浏览 收藏
-
- Golang · Go教程 | 56分钟前 |
- Go go-pretty 怎样把同一组行导出成 Markdown 表格
- 136浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go go-runewidth 怎样按显示列数折行
- 273浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go uniseg 怎样判断一段文本允许换行的位置
- 262浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 799次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 792次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 878次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 848次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 680次使用
-
- Java 性能优化上线清单:从定位、改造到灰度发布
- 2026-06-11 860浏览
-
- Spring Boot 压测验证:Gatling、JMeter 与性能回归门禁
- 2026-06-11 843浏览
-
- Java NMT 非堆内存排查:Direct Buffer、线程栈与 Metaspace 分析
- 2026-06-11 826浏览
-
- Spring Boot 容器内存优化:JVM 堆、非堆与 MaxRAMPercentage
- 2026-06-11 809浏览
-
- Tomcat 连接与线程参数调优:maxThreads、acceptCount 与 KeepAlive
- 2026-06-11 792浏览

