Golang怎么做国际化多语言_Golang i18n教程【核心】

张开发
2026/4/13 9:13:06 15 分钟阅读

分享文章

Golang怎么做国际化多语言_Golang i18n教程【核心】
go-i18n/v2 是最稳选择因 golang.org/x/text/message 不支持运行时语言切换其 Printer 一旦创建格式即固化它适合短文本格式化而非按请求绑定语言的页面文案场景。go-i18n/v2 是目前最稳的选择别用 golang.org/x/text/message 做运行时语言切换它压根不是为动态语言切换设计的message.NewPrinter 一创建格式规则就固化了。改 language.Tag 或系统 locale 都没用printer.Printf(Hello) 还是输出英文——你看到的不是“没切成功”而是“根本没打算支持”。常见错误现象注册了翻译但始终 fallback 到源字符串因为漏了 message.Catalog 绑定以为 reload 文件就能生效结果静默失败message.Printer 不支持热重载golang.org/x/text/message 适合短文本格式化如数字、日期但不适合页面文案、错误提示这类需按请求绑定语言的场景真正要的是按请求绑定语言go-i18n/v2 自带 Bundle 管理、Localizer 实例化、热重载注意仅对文件系统有效embed.FS 中需手动检查 fs.Stat资源文件命名和结构必须严格符合 BCP 47 JSON Schema错一个字符bundle.ParseFS 就会静默失败返回空字符串而非报错。文件名必须是 active.zh-CN.json不能是 zh.json、zh_CN.json 或 cn.json路径必须匹配 os.DirFS(./locales) 下的真实层级比如 ./locales/active.en-US.jsonJSON 内容必须严格{welcome: {description: homepage greeting, translation: 欢迎}} ?{welcome: 欢迎} ?缺少 description 和外层对象结构{welcome: {msg: 欢迎}} ?字段名必须是 translation只加载 active.* 前缀的文件inactive.* 会被忽略——这是故意设计避免误加载未审核翻译Accept-Language 解析不能直接信 r.Header.Get(Accept-Language)原始 header 可能为空、超长、含非法 tag如 en;q0.9, fr-XX;q0.8甚至触发 panic。正确做法是用 language.ParseAcceptLanguage它自动排序、过滤无效项、做标准化再配合已注册语言集做安全匹配先调 language.ParseAcceptLanguage(r.Header.Get(Accept-Language)) 得到有序候选列表遍历该列表用 language.MatchStrings(supportedLangs, candidate.String()) 查第一个合法匹配没匹配上就 fallback 到默认语言如 language.Make(en)别硬 fallback 到 en-US缓存解析结果避免每次请求都重复调 language.Parse——它不是纯函数内部有 map 查找开销HTTP 请求中怎么动态切换语言而不重启服务不能每次请求都新建 *i18n.Localizer它不是 goroutine-safe 的且初始化开销大也不能全局单例一个 localizer因为语言要随请求变化。 Mokker AI AI产品图添加背景

更多文章