golang常用库之-go-i18n库(国际化)
文章目录
- golang常用库之-go-i18n库(国际化)
- 关于i18n(国际化)
- go-i18n库
- 支持多种格式
- go-i18n 初始化设置了默认语言
- 默认语言的作用
- `go-i18n` 查找翻译的完整过程
- 1. 创建本地化器
- . 语言查找顺序
- 理解 `go-i18n` 的 `LocalizeConfig` 和翻译查找机制
- `LocalizeConfig` 结构解析
- `go-i18n` 查找翻译的完整过程
- 1. 创建一个Bundle
- 2. 确定消息查找方式
- 3. 语言查找顺序
- 4. 文件中的消息格式
- 1. 标准格式(推荐)
- 2. 带哈希的格式
- 3. 嵌套表格格式
golang常用库之-go-i18n库(国际化)
关于i18n(国际化)
国际化称作 i18n,其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数。由于软件发行可能面向多个国家,对于不同国家的用户,软件显示不同语言的过程就是国际化。通常来讲,软件中的国际化是通过配置文件来实现的,假设要支撑两种语言,那么就需要两个版本的配置文件。
现在大部分的应用基本都是前后端分离架构,但是只要有需要后端渲染的功能,则后端依然会存在国际化的场景。
例如:下载 Excel,导出 PDF,发送邮件通知等。
这些场景中的通用语言可以使用 i18n 国际化的方式进行开发维护。
国际化的标准做法是每种语言模式定义一个通用语言的模板文件。
业务代码根据当前上下文中的语言模式,从对应的语言模版中提取通用语言对应的语种的表达。
go-i18n库
github官方:https://github.com/nicksnyder/go-i18n
go-i18n是Go语言的国际化库,提供全面的国际化功能及命令行工具goi18n,用于管理翻译文件。它简化了多语言支持,并能处理复数形式和变量替换等复杂语言规则。
变量替换是利用text/template
语法在翻译字符串中嵌入变量,从而增强翻译的灵活性。
支持多种格式
- 支持任何格式的消息文件(例如 JSON、TOML、YAML)。
go-i18n
支持多种格式,包括 JSON、TOML 和 YAML
特性 | JSON | YAML | TOML |
---|---|---|---|
可读性 | 低(无注释,严格语法) | 高(支持注释,缩进分层) | 高(支持注释,键值对清晰) |
维护性 | 较差(易格式错误) | 中等(缩进敏感) | 高(无缩进问题) |
动态参数支持 | 支持(需转义) | 支持 | 支持 |
多语言工具支持 | 广泛支持 | 广泛支持 | 支持(需确认工具链) |
适合场景 | 机器生成/API 数据交换 | 复杂配置/多层级数据 | 人类可读的配置文件 |
- 优先 TOML
go-i18n
原生支持 TOML,且语法比 JSON 更友好。- 适合你的翻译内容结构(模块化分类 + 动态参数)。
- 次选 YAML
- 如果团队更熟悉 YAML,且需要复杂嵌套。
- 避免 JSON
- 除非有其他强制需求(如与前端共享翻译文件)。
使用你的 TOML 格式的国际化文件和 go-i18n 库
-
安装依赖
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u github.com/BurntSushi/toml
go-i18n 初始化设置了默认语言
在 go-i18n 库中,i18n.NewBundle(language.Chinese)
只是设置了默认语言(fallback language),而不是仅初始化中文翻译。
默认语言的作用
- 当请求的语言没有对应翻译时,会使用默认语言的翻译
- 当特定键在请求语言中不存在时,会尝试使用默认语言的翻译
go-i18n
查找翻译的完整过程
1. 创建本地化器
localizer := i18n.NewLocalizer(bundle, "zh-CN")
这一步创建了一个特定语言(这里是中文)的本地化器。您可以提供多个语言标签,表示语言的优先级:
localizer := i18n.NewLocalizer(bundle, "en-US", "en")
LocalizeConfig
结构体支持多种方式来指定要查找的消息:
// LocalizeConfig configures a call to the Localize method on Localizer.
type LocalizeConfig struct {// MessageID is the id of the message to lookup.// This field is ignored if DefaultMessage is set.MessageID string// TemplateData is the data passed when executing the message's template.// If TemplateData is nil and PluralCount is not nil, then the message template// will be executed with data that contains the plural count.TemplateData interface{}// PluralCount determines which plural form of the message is used.PluralCount interface{}// DefaultMessage is used if the message is not found in any message files.DefaultMessage *Message// Funcs is used to configure a template.TextParser if TemplateParser is not set.Funcs texttemplate.FuncMap// The TemplateParser to use for parsing templates.// If one is not set, a template.TextParser is used (configured with Funcs if it is set).TemplateParser template.Parser
}
. 语言查找顺序
假设本地化器配置为 i18n.NewLocalizer(bundle, "zh-CN", "zh", "en")
,那么查找顺序是:
- 尝试在
zh-CN
语言文件中查找指定的MessageID
- 如果未找到,尝试在
zh
(通用中文)中查找 - 如果仍未找到,尝试在
en
(英语)中查找 - 如果所有指定语言都没找到,尝试使用默认语言(创建 Bundle 时指定的)
- 如果仍未找到,返回错误
理解 go-i18n
的 LocalizeConfig
和翻译查找机制
LocalizeConfig
结构解析
i18n.LocalizeConfig
是 go-i18n 库中用于配置本地化请求的结构体。这个结构体定义了如何查找和处理翻译消息。
lc := &i18n.LocalizeConfig{MessageID: key,
}
在这段代码中:
MessageID
: 指定要查找的翻译消息的唯一标识符(键)- 这个键会被用来在翻译文件中查找对应的消息
go-i18n
查找翻译的完整过程
当您调用 localizer.Localize(lc)
时,go-i18n 按照以下步骤查找匹配的翻译:
1. 创建一个Bundle
创建一个Bundle以供应用程序在其整个生命周期内使用。
localizer := i18n.NewLocalizer(bundle, "zh-CN")
这一步创建了一个特定语言(这里是中文)的本地化器。您可以提供多个语言标签,表示语言的优先级:
// 优先尝试美式英语,其次是通用英语,最后回退到默认语言
localizer := i18n.NewLocalizer(bundle, "en-US", "en")
在初始化期间将翻译加载到您的bundle中。
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.LoadMessageFile("es.toml")
// If use go:embed
//go:embed locale.*.toml
var LocaleFS embed.FSbundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.LoadMessageFileFS(LocaleFS, "locale.es.toml")
2. 确定消息查找方式
LocalizeConfig
结构体支持多种方式来指定要查找的消息:
type LocalizeConfig struct {// 通过ID查找消息MessageID string// 直接提供默认消息DefaultMessage *Message// 提供模板数据(参数)TemplateData interface{}// 复数数量,用于复数形式PluralCount interface{}// 自定义模板函数TemplateFunc func(data string) (string, error)
}
在您的例子中,只使用了 MessageID
来查找消息。
3. 语言查找顺序
假设本地化器配置为 i18n.NewLocalizer(bundle, "zh-CN", "zh", "en")
,那么查找顺序是:
- 尝试在
zh-CN
语言文件中查找指定的MessageID
- 如果未找到,尝试在
zh
(通用中文)中查找 - 如果仍未找到,尝试在
en
(英语)中查找 - 如果所有指定语言都没找到,尝试使用默认语言(创建 Bundle 时指定的)
- 如果仍未找到,返回错误
4. 文件中的消息格式
在 TOML 翻译文件中,消息通常定义如下:
[admin.add]
description = "添加管理员操作" # 可选的描述,帮助翻译人员理解上下文
other = "添加管理员" # 默认形式
当执行以下代码时:
localizer := i18n.NewLocalizer(bundle, "zh-CN")
translation, err := localizer.Localize(&i18n.LocalizeConfig{MessageID: "admin.add",
})
MessageID 这个属性很重要,通过这个属性定位到使用 toml 中哪个数据。
go-i18n toml翻译文件格式,主要有:
1. 标准格式(推荐)
[greeting]
other = "Hello"[user.login.success]
other = "User {{.Name}} logged in successfully"
2. 带哈希的格式
[HelloPerson]
hash = "sha1-5b49bfdad81fedaeefb224b0ffc2acc58b09cff5"
other = "Hola {{.Name}}"
这种格式通常是由 go-i18n 的命令行工具自动生成的,哈希值有助于跟踪消息的变化。
3. 嵌套表格格式
[content.login]
success = "User logged in"
failure = "Login failed"
这种格式使用 TOML 的嵌套表格来组织翻译,但在 go-i18n 中使用时,完整的键是 content.login.success
。