i18n

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2025 License: Apache-2.0 Imports: 23 Imported by: 0

README

Gousing i18n 国际化工具包

介绍

Golang i18n 开箱即用的 i18n 工具包.

  • 提供极简文本消息和灵活的复数规则消息格式化支持
  • 支持语言消息分组, 消息文本支持 Golang 格式化占位符
    • 对于普通消息, 支持 fmt 格式化占位符, 如消息文本无自定义格式化占位符, 但 T 函数传递了多余的附加参数,则直接使用 fmt.Sprint 拼接参数到 Text 文本后输出
    • 对于复数消息, 支持 fmt 格式化占位符, 如消息文本无自定义格式化占位符, 但 T 函数传递了多余的附加参数,则直接丢弃多余的参数
  • 同一语言或不同语言支持单文件/多文件加载或文件夹加载
  • 支持 JSON、YAML 和 Toml 格式编码为 UTF8 消息语言包文件
  • 提供 Map, Messages, Bytes 多格式格式数据互转, 方便数据导入和导出

语言包文件参考 ./_testing/languages

使用
go get gitee.com/gousing/i18n
import  "gitee.com/gousing/i18n"
// 获取默认的国际化多语言包管理器
i18n.GetDefaultBundle()
// 创建国际化资源包实例
myBundle := i18n.NewBundle()

// 设置默认语言(用于回退)
i18n.SetDefaultLang("en")
// myBundle.SetDefaultLang("en")
// LoadWithFolder 从文件夹中加载语言包数据
//   - folder 文件夹路径, 支持JSON、YAML和Toml格式编码为UTF8
//   - 自动读取文件夹中的语言文件, 仅读取指定文件夹及下一级文件夹中的文件
//   - 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
//   - 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
//   - 如果文件夹为空或不存在JSON、YAML和Toml文件,则什么也不做
//   - 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据
i18n.LoadWithFolder("./languages")
//myBundle.LoadWithFolder("./languages")

// 设置单个消息,如果键不存在则创建新条目,如果已存在,则合并
i18n.SetOneMessage("en","welcome","Hello, %s!")
//myBundle.SetOneMessage("en","welcome","Hello, %s!")
i18n.SetOneMessage("en","someKey","this is someKey message.")
i18n.SetOneMessage("en","group.keyName","this is groupKey message, display %v, time: %s.")
i18n.SetOneMessage("en", "hasCats", MustPluralMessage([][]string{
	{"N2:=0", "%s has no cat."},
	{"N2:=1", "%s has one cat."},
	{"Y2:>1", "%s has %d cats."},
}))
i18n.SetOneMessage("zh-CN", "hasCats", MustMessage("有 %d 只猫。"))
i18n.SetOneMessage("en", "oddCats", MustPluralMessage([][]string{
	{"N1:=0", "has no cat."},
	{"N1:%2=0", "has an odd number of cats."},
	{"N1:%2=1", "has an even number of cats."},
}))
i18n.SetOneMessage("zh-CN", "oddCats", MustPluralMessage([][]string{
	{"N1:=0", "没有猫"},
	{"N1:%2=0", "有奇数只猫"},
	{"N1:%2=1", "有偶数只猫"},
}))
	b.SetOneMessage("ru", "hasCats", MustPluralMessage([][]string{
		// 0
		{"N1:<1", "Нет кошек."},
		// 1
		{"N1:=1", "Есть 1 кошка."},
		// 2-4
		{"Y1:[2,3,4]", "Есть %d кошки."},
		// 21, 31, 41, 51, 61...
		{"Y1:%10 = 1; %100 != 11", "Есть %d кот."},
		// 2-4, 22-24, 32-34...
		{"Y1:%10 [2, 3, 4]; %100 ![12, 13, 14]", "Есть %d кошки."},
		// 5-20, 25-30, 35-40...
		{"Y1:%10 = 0", "Есть %d кошек."},
		{"Y1:%10 ![5, 6, 7, 8, 9]", "Есть %d кошек."},
		{"Y1:%100 ![11, 12, 13, 14]", "Есть %d кошек."},
		// other
		{"Y1:>0", "Есть %d кошек."},
	}))
//

// NewLocalizer 使用默认 Bundle 管理器创建本地化器,解析用户接受的语言
// 	 - 支持精确匹配明确的语言名称,例如:zh zh-CN zh-Hans en en-US 等简短格式的语言标签
// 	 - 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表,例如:
// 	 - zh;q=0.8,en;q=0.5,en-US;q=0.3
// 	 - zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
loc:=i18n.NewLocalizer(acceptedLangs ...string)
// loc:=myBundle.NewLocalizer(acceptedLangs ...string)
// 使用本地化器查找翻译消息
loc.T("welcome","jackson")
loc.T("someKey")
loc.T("group.keyName","someVal",time.Now())
loc.T("hasCats","jackson", 10)
loc.T("oddCats", 1313)
消息示例
// en
{
  "action": {
    "add": "Add",
    "agree": "Agree",
    "apply": "Apply",
    "back": "Back",
    "cancel": "Cancel",
    "checkbox": "Checkbox",
    "clear": "Clear",
    "click": "Click",
    "close": "Close",
    "confirm": "Confirm",
    "confirms": {
      "apply": "Are you sure you want to apply?",
      "cancel": "Are you sure you want to cancel?",
      "clear": "Are you sure you want to clear?",
      "close": "Are you sure you want to close?",
      "delete": "Are you sure you want to delete?",
      "restore": "Are you sure you want to restore?",
      "save": "Are you sure you want to save?",
      "submit": "Are you sure you want to submit?"
    }
  },
  "plural": [
    ["N1:=0", "has no cat."],
    ["N1:=1", "has one cat."],
    ["Y1:>1", "has %d cats."]
  ]
}
// ru
{
  "text": "кошек",
  "plural": [
    // 0
    ["N1:<1", "Нет кошек."],
    // 1
    ["N1:=1", "Есть 1 кошка."],
    // 2-4
    ["Y1:[2,3,4]", "Есть %d кошки."],
    // 21, 31, 41, 51, 61...
    ["Y1:%10 = 1; %100 != 11", "Есть %d кот."],
    // 2-4, 22-24, 32-34...
    ["Y1:%10 [2, 3, 4]; %100 ![12, 13, 14]", "Есть %d кошки."],
    // 5-20, 25-30, 35-40...
    ["Y1:%10 = 0", "Есть %d кошек."],
    ["Y1:%10 ![5, 6, 7, 8, 9]", "Есть %d кошек."],
    ["Y1:%100 ![11, 12, 13, 14]", "Есть %d кошек."],
    // other
    ["Y1:>0", "Есть %d кошек."]
  ]
}
复数文本规则表达式

格式为 " BI : CompareType + CompareVal; CompareType + CompareVal... "

规则由半角字符(ASCII 字符)定义, 包含的空白字符及非 ASCII 字符将被忽略

  • B 是一个用 YN 表示的布尔值, 其含义是 msgText 中是否包含有显示 Count 参数对应的"%d"占位符
  • BY 时表示 msgText 中有 Count 参数对应的"%d"占位符,则会保留 T 函数 args... 中的 Count 参数进行格式化输出
  • BN 时即不包含,则会将 T 函数附加 args... 参数中的 Count 参数剔除后再对 Text 行格式化输出
  • I 是一个正整数, 表示 Count 参数在 T 函数 args... 参数中的索引位置, 从 1 开始计数, 同一 Key 下的全部复数文本规则的 Count 参数的索引值必须一致
  • I1 如: Y1 表示 Count 参数在 T 函数 args... 参数中的第 1 个位置, 即第 1 个参数为 Count 参数
  • I2 如: Y2 表示 Count 参数在 T 函数 args... 参数中的第 2 个位置, 即第 2 个参数为 Count 参数

CompareType 表示比较类型, 如 ">", "<", "=", "!=", "%" 等 16 种比较类型

CompareVal 表示比较值, 如 "0","1", "2", "-100" 等整数值,示例:

  • " N1:<1 " 表示当 Count 参数小于 1 时使用该文本, 且 msgText 不包含 Count:"%d"占位符, 如 "has no item"
  • " N1:=1 " 表示当 Count 参数等于 1 时使用该文本, 且 msgText 不包含 Count:"%d"占位符, 如 "has one item"
  • " Y1:>2 " 表示当 Count 参数大于 2 时使用该文本, 且 msgText 包含 Count:"%d"占位符, 如 "has %d items"

支持取模后比较 %

  • " Y1:%2=1 " 表示 Count % 2 取模后等于 1 时使用该文本
  • " N1:%10=[1,2,3] " 表示当 Count % 10 取模后 [1,2,3] 清单中时使用该文本

支持清单比较: [1,2,3], ![1,2,3]

  • " N1:[1,2,3] " 表示当 Count 参数在[1,2,3]清单中时使用该文本
  • " N1:![1,2,3] " 表示当 Count 参数不在[1,2,3]清单中时使用该文本

支持 AND 并联多个比较条件 ( 用分号分隔 )

  • " N1:>1; < 3 " 表示当 Count 参数 大于 1 且小于 3 时使用该文本
  • " Y1:>1; <30; %10=1 " 表示当 Count 参数大于 1 且小于 30, 且 Count % 10 取模后等于 1 时使用该文本
  • " Y1:>=10; <=100; %10=1 " 表示当 Count 参数大于等于 10 且小于等于 100, 且 Count % 10 取模后等于 1 时使用该文本
  • " Y1:>100; %100[1,2,3] " 表示当 Count 参数大于 100, 且 Count % 100 取模后在 [1,2,3] 清单中时使用该文本
Localizer 工具
// NewLocalizer 使用默认 Bundle 管理器创建本地化器,解析用户接受的语言
// 	 - 支持精确匹配明确的语言名称,例如:zh zh-CN zh-Hans en en-US 等简短格式的语言标签
// 	 - 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表,例如:
// 	 - zh;q=0.8,en;q=0.5,en-US;q=0.3
// 	 - zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
i18n.NewLocalizer(acceptedLangs ...string) *Localizer
// T 翻译方法,依据 Localizer 语言包进行查询翻译
//   - 如果找不到,则尝试回退到默认语言包, 否则返回原始 key 字符串
func (l *Localizer) T(key string, args ...any) string
// Bundle 获取本地化器绑定的语言包管理器
func (l *Localizer) Bundle() *Bundle
// LangName 获取实际支持的语言名称
func (l *Localizer) LangName() string
// String 实现 fmt.Stringer 接口,返回实际支持的语言名称
func (l *Localizer) String() string
Default 工具
// GetDefaultBundle 获取默认的多语言包管理器
//   - 首次调用时, 如为用户设置默认的多语言包管理器,则自动初始化一个新的多语言包管理器
//   - 该管理器无默认语言的空语言包管理器
i18n.GetDefaultBundle() *Bundle
// SetDefaultBundle 设置默认的多语言包管理器
i18n.SetDefaultBundle(b *Bundle)
// GetDefaultLocalizer 获取针对默认的多语言包管理器的默认语言本地化器
//   - 修改默认语言时会自动更新该默认本地化器
i18n.GetDefaultLocalizer() *Localizer
// SetDefaultLocalizer 设置针对默认的多语言包管理器的默认语言本地化器
i18n.SetDefaultLocalizer(loc *Localizer)
// T 翻译方法,使用默认语言包管理器的默认语言本地化器进行查询翻译
//   - 如果找不到,否则返回原始 key 字符串
i18n.T(key string, args ...any) string
Bundle 工具
// NewBundle 创建新的国际化资源包
i18n.NewBundle() *Bundle
// GetOneMessage 获取指定语言名称和语言Key的文本消息
//   - 如果不存在则返回nil和false
func (b *Bundle) GetOneMessage(langName, key string) (*Message, bool)
i18n.GetOneMessage(langName, key string) (*Message, bool)
// GetOneMessage 获取指定语言名称和语言Key的文本消息
//   - 如果不存在则返回nil和false
func (b *Bundle) GetOneMessage(langName, key string) (*Message, bool)
i18n.GetOneMessage(langName, key string) (*Message, bool)
// GetMessages 获取指定语言名称的所有消息
//   - 返回 FlatMapMessages 扁平化消息数据(一维平铺的的消息数据))
//   - 返回的是复制数据,防止外部修改影响内部数据
//   - 如果指定语言不存在则返回nil
func (b *Bundle) GetMessages(langName string) FlatMapMessages
i18n.GetMessages(langName string) FlatMapMessages
// SetOneMessage 设置单个消息,如果键不存在则创建新条目,如果已存在,则合并
func (b *Bundle) SetOneMessage(langName, key string, msg *Message) error
i18n.SetOneMessage(langName, key string, msg *Message) error
// SetMessages 设置一组消息,如果键不存在则创建新条目,如果已存在,则合并
func (b *Bundle) SetMessages(langName string, data FlatMapMessages) error
i18n.SetMessages(langName string, data FlatMapMessages) error
// HasDefaultLang 检查是否存在默认语言设置
func (b *Bundle) HasDefaultLang() bool
i18n.HasDefaultLang() bool
// GetDefaultLang 获取默认语言,例如:zh-CN, en-US 等简短格式的语言标签
func (b *Bundle) GetDefaultLang() string
i18n.GetDefaultLang() string
// SetDefaultLang 设置默认语言,例如:zh-CN, en-US 等简短格式的语言标签
func (b *Bundle) SetDefaultLang(lang string) error
i18n.SetDefaultLang(lang string) error
// GetSupportedLangs 获取支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签
func (b *Bundle) GetSupportedLangs() []string
i18n.GetSupportedLangs() []string
// SetSupportedLangs 设置支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签
func (b *Bundle) SetSupportedLangs(supportedLangs ...string) error
i18n.SetSupportedLangs(supportedLangs ...string) error
// HasSupportedLangName 检查指定的语言名称是否受支持,例如:zh-CN, en-US 等简短格式的语言标签
func (b *Bundle) HasSupportedLangName(lang string) bool
i18n.HasSupportedLangName(lang string) bool
// HasSupportedLangTag 检查指定的语言标签是否受支持,例如:language.Eanglish | language.SimplifiedChinese 等语言标签
func (b *Bundle) HasSupportedLangTag(tag language.Tag) bool
i18n.HasSupportedLangTag(tag language.Tag) bool
Message 工具
// NewMessage 创建新的普通消息对象, 如果为空则返回错误
i18n.NewMessage(text string) (*Message, error)
// MustMessage 创建新的普通消息对象, 如果为空则panic错误
i18n.MustMessage(text string) *Message
// NewPluralMessage 创建复数消息对象,如果解析失败则返回错误
//   - ParsePluralMessage 函数别名
i18n.NewPluralMessage(rules [][]string) (*Message, error)
// MustPluralMessage 必须创建复数消息对象,如果解析失败则panic错误
i18n.MustPluralMessage(rules [][]string) *Message

// ParseMessage 格式化及校验消息结构, 自动进行ParseKey处理, 并检查Text/Plural/Group字段有效性
//   - Text/Plural 字段对应两种消息类型,不能同时被设置,只能选择其一
i18n.ParseMessage(msg *Message) error
// ParsePluralMessage 格式化及检查校验复数消息表达式
//   - rules := [][]string{ {`countRule`,`msgText`}... }
//   - JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
//   - JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]
i18n.ParsePluralMessage(rules [][]string) (*PluralMessage, error)

// ParsePluralRule 解析复数文本规则表达式
i18n.ParsePluralRule(rule string) (rules []*CompareRule, index int, hasCount bool, err error)

// ParseKey 格式化消息键名, 统一为小驼峰命名规则(camelCase), 并校验是否为合法的键名
//   - 仅允许字母、字母+数字,以统一兼容语言包文件变量命名格式
//   - 任何非ASCII或不可打印字符都不允许出现在键名中
//   - 特殊约定:以一个下划线开始key为配置用途
//   - "_text","_plural","_group" 为系统保留配置键名, 不做为消息文本键名使用
//   - 如 "groupName.userName" => "GroupName.UserName"
//   - 如 "user_name" => "userName"
//   - 如 "user name " => "userName"
//   - 如 " user&name " => "userName"
//   - 如 "_lastName" => "_lastName"
i18n.ParseKey(key string) (string, error)
Utils 工具
// MapAnyToMessages 将 map[string]any 格式的嵌套消息文本 转换为 FlatMapMessages 类型的消息数据
//   - data: map[string]any 多级分组嵌套格式消息数据
//   - return: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
i18n.MapAnyToMessages(data map[string]any) (FlatMapMessages, error)
// MessagesToMapAny 将 FlatMapMessages 格式的平铺消息转换为 map[string]any 多级分组嵌套格式消息文本
//   - data: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
//   - return: map[string]any 多级分组嵌套格式消息数据
i18n.MessagesToMapAny(data FlatMapMessages) (map[string]any, error)

// MessagesToBytes 将 FlatMapMessages 导出为指定文件格式的字节切片数据,用于文件导出使用
//   - data:  FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据),通常为包含了同一种语言的全部消息数据
//   - format: 文件格式, 支持 json, toml, yaml, yml
i18n.MessagesToBytes(data FlatMapMessages, format string) ([]byte, error)

// PrintFlatMapMessages 格式化打印 FlatMapMessages 类型的消息数据为字符串,用于调试或查看数据结构
//   - data: FlatMapMessages  扁平化消息数据类型(一维平铺的的消息数据)
//   - return: string 格式化后的字符串
i18n.PrintFlatMapMessages(data FlatMapMessages) string
// PrintMapAnyMessages 格式化打印 map[string]any 类型的消息数据为字符串,用于调试或查看数据结构
//   - data: map[string]any 多级分组嵌套格式消息数据
//   - return: string 格式化后的字符串
i18n.PrintMapAnyMessages(data map[string]any) string
性能测试
Parse PluralRule
go.exe test -benchmem -run=^$ -bench ^Benchmark_ParsePluralRule* gitee.com/gousing/i18n -v
goos: windows
goarch: amd64
pkg: gitee.com/gousing/i18n
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
Benchmark_ParsePluralRule - - - -
Benchmark_ParsePluralRule/N1:=0 11207410 101.5 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:==0 11600389 100.8 ns/op 56 B/op 4allocs/op
Benchmark_ParsePluralRule/N1:!=0 11947942 102.2 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:>0 12190500 98.53 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:>=100 11097608 117.3 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:<-200 10288179 109.9 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:<=20 9665306 106.2 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:[0,1,2] 7475042 139.1 ns/op 80 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:![-1,2,-3];>0 4898826 231.2 ns/op 144 B/op 7 allocs/op
Benchmark_ParsePluralRule/N1:%2=_0 8660995 139.8 ns/op 72 B/op 4 allocs/op
Benchmark_ParsePluralRule/N1:>10;%-10[0,1,2,4,5] 3937257 304.3 ns/op 168 B/op 7 allocs/op
Benchmark_ParsePluralRule/Y3:==0 11861364 101.5 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/Y4:!=-1 11498096 103.8 ns/op 56 B/op 4 allocs/op
Benchmark_ParsePluralRule/Y5:>0;<=100 5870636 187.0 ns/op 120 B/op 7 allocs/op
Message Display
go.exe test -benchmem -run=^$ -bench ^Benchmark_Message_Display* gitee.com/gousing/i18n -v
goos: windows
goarch: amd64
pkg: gitee.com/gousing/i18n
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
Benchmark_Message_Display - - - -
Benchmark_Message_Display/NoFormat 508901967 2.328 ns/op 0 B/op 0 allocs/op
Benchmark_Message_Display/1Format 17931684 67.49 ns/op 24 B/op 1 allocs/op
Benchmark_Message_Display/2Format 12727678 82.55 ns/op 16 B/op 1 allocs/op
PluralMessage Display
go.exe test -benchmem -run=^$ -bench ^Benchmark_PluralMessage_Display* gitee.com/gousing/i18n -v
goos: windows
goarch: amd64
pkg: gitee.com/gousing/i18n
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
Benchmark_PluralMessage_Display - - - -
Benchmark_PluralMessage_Display/NoFormat 84812868 14.30 ns/op 0 B/op 0 allocs/op
Benchmark_PluralMessage_Display/1Format 14168636 82.67 ns/op 16 B/op 1 allocs/op
Benchmark_PluralMessage_Display/2Format 9899029 122.1 ns/op 24 B/op 1 allocs/op
Gousing 通用选项
自定义 Logger
// 默认使用Golang标准库slog.Default()全局日志记录日志
// i18n.SetLogger(*slog.Logger)
myLogger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
i18n.SetLogger(myLogger)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrLoadBundleNil      = errors.New("i18n.Loader: bundle is nil")
	ErrLoadFolderEmpty    = errors.New("i18n.Loader: file folder is empty")
	ErrLoadFolderNotExist = errors.New("i18n.Loader: file folder not exist")
	ErrLoadFilePathEmpty  = errors.New("i18n.Loader: file path is empty")
	ErrLoadFileNotExist   = errors.New("i18n.Loader: file not exist")
	ErrLoadIoNil          = errors.New("i18n.Loader: io.Reader is nil")
	ErrLoadIoWith         = func(err error) error {
		return fmt.Errorf("i18n.Loader: io.Reader error, %v", err)
	}
	ErrLoadInvalidFormat   = errors.New("i18n.Loader: format is invalid, only supports 'JSON', 'YAML' or 'TOML'")
	ErrLoadLangNameEmpty   = errors.New("i18n.Loader: langName is empty")
	ErrLoadLangNameExtract = errors.New("i18n.Loader: Failed to extract langName from file path")
	ErrLoadLangNameInvalid = errors.New("i18n.Loader: langName is invalid, must be like 'en', 'en-US', 'zh' or 'zh-CN'")
	ErrLoadContentEmpty    = errors.New("i18n.Loader: content is empty")
	ErrLoadErrorEncoding   = errors.New("i18n.Loader: encoding error, only supports UTF-8")
	ErrLoadErrorWith       = func(err error) error {
		return fmt.Errorf("i18n.Loader: %v", err)
	}
)
View Source
var (
	ErrLangNameInvalid      = errors.New("langName is invalid")
	ErrLangNameEmpty        = errors.New("langName is empty")
	ErrLangNameShort        = errors.New("langName too short")
	ErrLangNameNotSupported = errors.New("langName is not supported")
)
View Source
var (
	ErrParseMessageNil           = errors.New("i18n.ParseMessage: value is nil")
	ErrParseMessageEmpty         = errors.New("i18n.ParseMessage: value is empty")
	ErrParseMessageTypesBeSet    = errors.New("i18n.ParseMessage: Both `value.Text` and `value.Plural` message types have been set, only one can be used")
	ErrParseMessageInvalidType   = errors.New("i18n.ParseMessage: invalid element type")
	ErrParseMessageInvalidText   = errors.New("i18n.ParseMessage: invalid `value.Text` element")
	ErrParseMessageInvalidPlural = errors.New("i18n.ParseMessage: invalid `value.Plural` element")
	ErrParseMessageInvalidGroup  = errors.New("i18n.ParseMessage: invalid `value.Group` element")
	ErrParseMessageEmptyText     = errors.New("i18n.ParseMessage: `value.Text` element is empty")
	ErrParseMessageEmptyPlural   = errors.New("i18n.ParseMessage: `value.Plural` element is empty")
	ErrParseMessageEmptyGroup    = errors.New("i18n.ParseMessage: `value.Group` element is empty")
	ErrParseKeyInvalid           = errors.New("i18n.ParseKey: invalid key")
	ErrParseKeyEmpty             = errors.New("i18n.ParseKey: key is empty")
)
View Source
var (
	ErrRuleParserNonASCII         = errors.New("ruleParser: rule contains Non-ASCII character")
	ErrRuleParserEmpty            = errors.New("ruleParser: rule is empty")
	ErrRuleParserInvalidLength    = errors.New("ruleParser: rule length is invalid, min length is 5")
	ErrRuleParserInvalidHasCount  = errors.New("ruleParser: invalid rule.HasCount, must start with 'Y/N'")
	ErrRuleParserInvalidIndex     = errors.New("ruleParser: invalid rule.Index, must be greater than 0")
	ErrRuleParserInvalidSeparator = errors.New("ruleParser: invalid rule.Separator, must start with ':'")
	ErrRuleParserInvalidType      = func(s string) error {
		return fmt.Errorf("ruleParser: invalid rule.Type: %s", s)
	}
	ErrRuleParserInvalidValue = func(s string) error {
		return fmt.Errorf("ruleParser: invalid rule.Value: %s", s)
	}
)

Functions

func GetDefaultLang

func GetDefaultLang() string

GetDefaultLang 获取默认语言,例如:zh-CN, en-US 等简短格式的语言标签

func GetLogger

func GetLogger() *slog.Logger

func GetSupportedLangs

func GetSupportedLangs() []string

GetSupportedLangs 获取支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签

func HasDefaultLang

func HasDefaultLang() bool

HasDefaultLang 检查是否存在默认语言设置

func HasSupportedLangName

func HasSupportedLangName(lang string) bool

HasSupportedLangName 检查指定的语言名称是否受支持,例如:zh-CN, en-US 等简短格式的语言标签

func HasSupportedLangTag

func HasSupportedLangTag(tag language.Tag) bool

HasSupportedLangTag 检查指定的语言标签是否受支持,例如:language.Eanglish | language.SimplifiedChinese 等语言标签

func LoadWithEmbedFS

func LoadWithEmbedFS(fs embed.FS, folder string) error

LoadWithEmbedFS 从EmbedFS文件夹中加载语言包数据到默认多语言包管理器

  • folder 文件夹路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动读取文件夹中的语言文件, 仅读取指定文件夹及下一级文件夹中的文件
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果文件夹为空或不存在JSON、YAML和Toml文件,则什么也不做
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func LoadWithFile

func LoadWithFile(filePath string) error

LoadWithFile 从指定的明确本地路径文件加载语言包数据到默认的多语言包管理器

  • filePath 文件路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func LoadWithFolder

func LoadWithFolder(folder string) error

LoadWithFolder 从本地文件夹中加载语言包数据到默认的多语言包管理器

  • folder 文件夹路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动读取文件夹中的语言文件, 仅读取指定文件夹及下一级文件夹中的文件
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果文件夹为空或不存在JSON、YAML和Toml文件,则什么也不做
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func LoadWithReader

func LoadWithReader(reader io.Reader, langName, format string) error

LoadWithReader 从Reader加载语言包数据到默认的多语言包管理器

  • reader io.Reader 读取器,可以是文件、内存等数据源的读取器
  • langName 指定明确的语言名称(标签), 如 "en-US"、"zh-CN"
  • format 指定明确的数据格式,如 "JSON","YAML"/"YML","TOML" (不区分大小写)
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func MessagesToBytes

func MessagesToBytes(data FlatMapMessages, format string) ([]byte, error)

MessagesToBytes 将 FlatMapMessages 导出为指定文件格式的字节切片数据,用于文件导出使用

  • data: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据),通常为包含了同一种语言的全部消息数据
  • format: 文件格式, 支持 json, toml, yaml, yml

func MessagesToMapAny

func MessagesToMapAny(data FlatMapMessages) (map[string]any, error)

MessagesToMapAny 将 FlatMapMessages 格式的平铺消息转换为 map[string]any 多级分组嵌套格式消息文本

  • data: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
  • return: map[string]any 多级分组嵌套格式消息数据

func ParseKey

func ParseKey(key string) (string, error)

ParseKey 格式化消息键名, 统一为小驼峰命名规则(camelCase), 并校验是否为合法的键名

  • 仅允许字母、字母+数字,以统一兼容语言包文件变量命名格式
  • 任何非ASCII或不可打印字符都不允许出现在键名中
  • 特殊约定:以一个下划线开始key为配置用途
  • "_text","_plural","_group" 为系统保留配置键名, 不做为消息文本键名使用
  • 如 "groupName.userName" => "GroupName.UserName"
  • 如 "user_name" => "userName"
  • 如 "user name " => "userName"
  • 如 " user&name " => "userName"
  • 如 "_lastName" => "_lastName"

func ParseLangName

func ParseLangName(langName string) (string, error)

ParseLangName 将 i18n 语言名称转换为标准化的格式,例如:

  • en => en
  • english => en
  • zh => zh
  • chinese => zh
  • zh_cn => zh-CN
  • zh-hans => zh-Hans

func ParseLangTag

func ParseLangTag(langName string) (language.Tag, error)

ParseLangTag 将 i18n 语言名称转换为标准库 language.Tag,例如:

  • en => language.English
  • english => language.English
  • en-US => language.AmericanEnglish
  • zh => language.Chinese
  • chinese => language.Chinese
  • zh-cn => zh-CN 非Golang内置语言Tag
  • zh-hans => language.SimplifiedChinese

func ParseMessage

func ParseMessage(msg *Message) error

ParseMessage 格式化及校验消息结构, 自动进行ParseKey处理, 并检查Text/Plural/Group字段有效性

  • Text/Plural 字段对应两种消息类型,不能同时被设置,只能选择其一

func PrintFlatMapMessages

func PrintFlatMapMessages(data FlatMapMessages) string

PrintFlatMapMessages 格式化打印 FlatMapMessages 类型的消息数据为字符串,用于调试或查看数据结构

  • data: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
  • return: string 格式化后的字符串

func PrintMapAnyMessages

func PrintMapAnyMessages(data map[string]any) string

PrintMapAnyMessages 格式化打印 map[string]any 类型的消息数据为字符串,用于调试或查看数据结构

  • data: map[string]any 多级分组嵌套格式消息数据
  • return: string 格式化后的字符串

func SetDefaultBundle

func SetDefaultBundle(b *Bundle)

SetDefaultBundle 设置默认的多语言包管理器

func SetDefaultLang

func SetDefaultLang(lang string) error

SetDefaultLang 设置默认语言,例如:zh-CN, en-US 等简短格式的语言标签

func SetDefaultLocalizer added in v1.0.1

func SetDefaultLocalizer(loc Localizer)

SetDefaultLocalizer 设置针对默认的多语言包管理器的默认语言本地化器

func SetLogger

func SetLogger(log *slog.Logger)

func SetMessages

func SetMessages(langName string, data FlatMapMessages) error

SetMessages 设置一组消息,如果键不存在则创建新条目,如果已存在,则合并

func SetOneMessage

func SetOneMessage(langName, key string, msg *Message) error

SetOneMessage 设置单个消息,如果键不存在则创建新条目,如果已存在,则合并

func SetSupportedLangs

func SetSupportedLangs(supportedLangs ...string) error

SetSupportedLangs 设置支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签

func T added in v1.0.1

func T(key string, args ...any) string

T 翻译方法,使用默认语言包管理器的默认语言本地化器进行查询翻译

  • 如果找不到,否则返回原始 key 字符串

Types

type Bundle

type Bundle struct {
	// contains filtered or unexported fields
}

Bundle 多语言包管理器

func GetDefaultBundle

func GetDefaultBundle() *Bundle

GetDefaultBundle 获取默认的多语言包管理器

  • 首次调用时, 如为用户设置默认的多语言包管理器,则自动初始化一个新的多语言包管理器
  • 该管理器无默认语言的空语言包管理器

func NewBundle

func NewBundle() *Bundle

NewBundle 创建新的国际化资源包

func (*Bundle) GetDefaultLang

func (b *Bundle) GetDefaultLang() string

GetDefaultLang 获取默认语言,例如:zh-CN, en-US 等简短格式的语言标签

func (*Bundle) GetMessages

func (b *Bundle) GetMessages(langName string) FlatMapMessages

GetMessages 获取指定语言名称的所有消息

  • 返回 FlatMapMessages 扁平化消息数据(一维平铺的的消息数据))
  • 返回的是复制数据,防止外部修改影响内部数据
  • 如果指定语言不存在则返回nil

func (*Bundle) GetOneMessage

func (b *Bundle) GetOneMessage(langName, key string) (*Message, bool)

GetOneMessage 获取指定语言名称和语言Key的文本消息

  • 如果不存在则返回nil和false

func (*Bundle) GetSupportedLangs

func (b *Bundle) GetSupportedLangs() []string

GetSupportedLangs 获取受支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签

func (*Bundle) HasDefaultLang

func (b *Bundle) HasDefaultLang() bool

HasDefaultLang 检查是否存在默认语言设置

func (*Bundle) HasSupportedLangName

func (b *Bundle) HasSupportedLangName(langName string) bool

HasSupportedLangName 检查指定的语言名称是否受支持,例如:zh-CN, en-US 等简短格式的语言标签

func (*Bundle) HasSupportedLangTag

func (b *Bundle) HasSupportedLangTag(tag language.Tag) bool

HasSupportedLangTag 检查指定的语言标签是否受支持,例如:language.Eanglish | language.SimplifiedChinese 等语言标签

func (*Bundle) LoadWithEmbedFS

func (b *Bundle) LoadWithEmbedFS(fs embed.FS, folder string) error

LoadWithEmbedFS 从EmbedFS文件夹中加载语言包数据到当前多语言包管理器

  • folder 文件夹路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动读取文件夹中的语言文件, 仅读取指定文件夹及下一级文件夹中的文件
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果文件夹为空或不存在JSON、YAML和Toml文件,则什么也不做
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func (*Bundle) LoadWithFile

func (b *Bundle) LoadWithFile(filePath string) error

LoadWithFile 从指定的明确本地路径文件加载语言包数据到当前多语言包管理器

  • filePath 文件路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func (*Bundle) LoadWithFolder

func (b *Bundle) LoadWithFolder(folder string) error

LoadWithFolder 从本地文件夹中加载语言包数据到当前多语言包管理器

  • folder 文件夹路径, 支持JSON、YAML和Toml格式编码为UTF8
  • 自动读取文件夹中的语言文件, 仅读取指定文件夹及下一级文件夹中的文件
  • 自动从文件路径中解析语言名称(标签), 文件名优先,文件夹名次选
  • 如 "folder/groupName.en-US.json", "folder/en-US.yml", "folder/en-US/fileName.json",
  • 如果文件夹为空或不存在JSON、YAML和Toml文件,则什么也不做
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func (*Bundle) LoadWithReader

func (b *Bundle) LoadWithReader(reader io.Reader, langName, format string) error

LoadWithReader 从Reader加载语言包数据到当前多语言包管理器

  • reader io.Reader 读取器,可以是文件、内存等数据源的读取器
  • langName 指定明确的语言名称(标签), 如 "en-US"、"zh-CN"
  • format 指定明确的数据格式,如 "JSON","YAML"/"YML","TOML" (不区分大小写)
  • 如果已加载过同名语言/同名KEY的语言包消息,则合并语言包数据

func (*Bundle) NewLocalizer

func (b *Bundle) NewLocalizer(acceptedLangs ...string) Localizer

NewLocalizer 创建本地化器,解析用户接受的语言

  • 支持精确匹配明确的语言名称,例如:zh zh-CN zh-Hans en en-US 等简短格式的语言标签
  • 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表,例如:
  • zh;q=0.8,en;q=0.5,en-US;q=0.3
  • zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

func (*Bundle) SetDefaultLang

func (b *Bundle) SetDefaultLang(langName string) error

SetDefaultLang 设置默认语言,例如:zh-CN, en-US 等简短格式的语言标签

func (*Bundle) SetMessages

func (b *Bundle) SetMessages(langName string, data FlatMapMessages) error

SetMessages 设置一组消息,如果键不存在则创建新条目,如果已存在,则合并

func (*Bundle) SetOneMessage

func (b *Bundle) SetOneMessage(langName string, key string, msg *Message) error

SetOneMessage 设置单个消息,如果键不存在则创建新条目,如果已存在,则合并

func (*Bundle) SetSupportedLangs

func (b *Bundle) SetSupportedLangs(langNames ...string) error

SetSupportedLangs 设置受支持的语言列表,例如:zh-CN, en-US 等简短格式的语言标签

type CompareRule

type CompareRule struct {
	// CompareType 比较符号(16) "=", "<", "<=", ">", ">=", "!=", "[", "![", "%D=", "%D!=", "%D<", "%D<=", "%D>", "%D>=", "%D[", "%D!["
	CompareType CompareType
	// CompareVals 比较值:Count和这一个值进行比较, 最少有一个值, 取模或列表有多个值
	CompareVals CompareVals
}

func ParsePluralRule

func ParsePluralRule(rule string) (rules []*CompareRule, index int, hasCount bool, err error)

ParsePluralRule 解析复数文本规则表达式

  • countRule 格式为 " BI : CompareType + CompareVal; CompareType + CompareVal... "
  • countRule 规则由半角字符(ASCII字符)定义, 包含的空白字符及非ASCII字符将被忽略
  • `B` 是一个用 `Y`或`N` 表示的布尔值, 其含义是 msgText 中是否包含有显示Count参数对应的"%d"占位符
  • `B` 为 `Y` 时表示 msgText 中有Count参数对应的"%d"占位符,则会保留T函数 args... 中的Count参数进行格式化输出
  • `B` 为 `N` 时即不包含,则会将T函数附加 args... 参数中的Count参数剔除后再对Text行格式化输出
  • `I` 是一个正整数, 表示Count参数在T函数 args... 参数中的索引位置, 从1开始计数, 同一Key下的全部复数文本规则的Count参数的索引值必须一致
  • `I` 为 `1` 如: Y1 表示Count参数在T函数 args... 参数中的第1个位置, 即第1个参数为Count参数
  • `I` 为 `2` 如: Y2 表示Count参数在T函数 args... 参数中的第2个位置, 即第2个参数为Count参数
  • `CompareType` 表示比较类型, 如 ">", "<", "=", "!=", "%" 等16种比较类型
  • `CompareVal` 表示比较值, 如 "0","1", "2", "-100" 等整数值
  • 示例:
  • " N1:<1 " 表示当Count参数小于1时使用该文本, 且 msgText 不包含Count:"%d"占位符, 如 "has no item"
  • " N1:=1 " 表示当Count参数等于1时使用该文本, 且 msgText 不包含Count:"%d"占位符, 如 "has one item"
  • " Y1:>2 " 表示当Count参数大于2时使用该文本, 且 msgText 包含Count:"%d"占位符, 如 "has %d items"
  • 支持取模后比较 %
  • " Y1:%2=1 " 表示 Count % 2 取模后等于1时使用该文本
  • " N1:%10=[1,2,3] " 表示当 Count % 10 取模后 [1,2,3] 清单中时使用该文本
  • 支持清单比较: [1,2,3], ![1,2,3]
  • " N1:[1,2,3] " 表示当Count参数在[1,2,3]清单中时使用该文本
  • " N1:![1,2,3] " 表示当Count参数不在[1,2,3]清单中时使用该文本
  • 支持AND并联多个比较条件 ( 用分号分隔 ) 如 "N1:>=1;<3" 表示大于等于1且小于3
  • " N1:>1; <3 " 表示当 Count参数 大于1且小于3时使用该文本
  • " Y1:>1; <30; %10=1 " 表示当 Count 参数大于1且小于30, 且 Count % 10 取模后等于1时使用该文本
  • " Y1:>=10; <=100; %10=1 " 表示当 Count 参数大于等于10且小于等于100, 且 Count % 10 取模后等于1时使用该文本
  • " Y1:>100; %100[1,2,3] " 表示当 Count 参数大于100, 且 Count % 100 取模后在 [1,2,3] 清单中时使用该文本

func (CompareRule) String

func (c CompareRule) String() string

type CompareType

type CompareType uint8
const (
	CompareTypeEqual             CompareType = iota + 1 // =    Count 等于
	CompareTypeLess                                     // <    Count 小于
	CompareTypeLessOrEqual                              // <=   Count 小于等于
	CompareTypeGreater                                  // > 	  Count 大于
	CompareTypeGreaterOrEqual                           // >=   Count 大于等于
	CompareTypeNotEqual                                 // !=   Count 不等于
	CompareTypeInList                                   // [    Count 在列表中
	CompareTypeNotInList                                // ![   Count 不在列表中
	CompareTypeModEqual                                 // %D=  Count % D 取模后等于
	CompareTypeModNotEqual                              // %D!= Count % D 取模后不等于
	CompareTypeModLess                                  // %D<  Count % D 取模后小于
	CompareTypeModLessOrEqual                           // %D<= Count % D 取模后小于等于
	CompareTypeModGreater                               // %D>  Count % D 取模后大于
	CompareTypeModGreaterOrEqual                        // %D>= Count % D 取模后大于等于
	CompareTypeModInList                                // %D[  Count % D 取模后在列表中
	CompareTypeModNotInList                             // %D![ Count % D 取模后不在列表中
)

func ParseCompareType

func ParseCompareType(compareStr string) (CompareType, bool)

func (CompareType) String

func (c CompareType) String() string

type CompareVals

type CompareVals []int

func (CompareVals) Len

func (c CompareVals) Len() int

func (CompareVals) String

func (c CompareVals) String() string

func (CompareVals) StringWithNotFirst

func (c CompareVals) StringWithNotFirst() string

type FlatMapMessages

type FlatMapMessages map[string]*Message

FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据), 用于存储和查找单个语言的所有消息文本

  • key: 消息键名(已通过 ParseKey 校验的一级键名或多级组合键名)
  • key: 如 "keyName","groupName.subName.keyName"
  • value: *Message 消息

func GetMessages

func GetMessages(langName string) FlatMapMessages

GetMessages 获取指定语言名称的所有消息

  • 返回 FlatMapMessages 扁平化消息数据(一维平铺的的消息数据))
  • 返回的是复制数据,防止外部修改影响内部数据
  • 如果指定语言不存在则返回nil

func MapAnyToMessages

func MapAnyToMessages(data map[string]any) (FlatMapMessages, error)

MapAnyToMessages 将 map[string]any 格式的嵌套消息文本 转换为 FlatMapMessages 类型的消息数据

  • data: map[string]any 多级分组嵌套格式消息数据
  • return: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)

type Localizer

type Localizer interface {
	// T 翻译方法,使用默认语言包管理器的默认语言本地化器进行查询翻译
	//   - 如果找不到,否则返回原始 key 字符串
	T(key string, args ...any) string
	// Bundle 获取本地化器绑定的语言包管理器
	Bundle() *Bundle
	// LangName 获取实际支持的语言名称
	LangName() string
	// String 实现 fmt.Stringer 接口,返回实际支持的语言名称
	String() string
}

Localizer i18n本地化器,封装语言匹配和回退逻辑

func GetDefaultLocalizer added in v1.0.1

func GetDefaultLocalizer() Localizer

GetDefaultLocalizer 获取针对默认的多语言包管理器的默认语言本地化器

  • 修改默认语言设置时会自动更新该默认本地化器

func NewLocalizer

func NewLocalizer(acceptedLangs ...string) Localizer

NewLocalizer 使用默认 Bundle 管理器创建本地化器,解析用户接受的语言

  • 支持精确匹配明确的语言名称,例如:zh zh-CN zh-Hans en en-US 等简短格式的语言标签
  • 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表,例如:
  • zh;q=0.8,en;q=0.5,en-US;q=0.3
  • zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

type Message

type Message struct {
	Text   string
	Plural *PluralMessage
}

Message 单条语言消息,支持普通消息和复数消息

  • Text/Plural 字段对应两种消息类型,不能同时被设置,只能选择其一
  • Text/Plural 字段不能同时为空
  • Text 普通消息文本, 支持包含 fmt.Sprintf 格式化字符, 如 "Welcome %s!", 其中 %s 为参数占位符
  • Text 为空时自动处理为"", 表示当且节点为一个分组或使用Plural
  • Plural 复数消息文本, 至少要设置2个复数字段, 支持自定义Plural规则和其他更多复数表示的字符串字段
  • Plural 为空时自动处理为nil, 表示当且节点为一个分组或使用Text

func GetOneMessage

func GetOneMessage(langName, key string) (*Message, bool)

GetOneMessage 获取指定语言名称和语言Key的文本消息

  • 如果不存在则返回nil和false

func MustMessage

func MustMessage(text string) *Message

MustMessage 创建新的普通消息对象, 如果为空则panic错误

func MustPluralMessage

func MustPluralMessage(rules [][]string) *Message

MustPluralMessage 必须创建复数消息对象,如果解析失败则panic错误

  • rules := [][]string{ {`countRule`,`msgText`}... }
  • JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
  • JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]

func NewMessage

func NewMessage(text string) (*Message, error)

NewMessage 创建新的普通消息对象, 如果为空则返回错误

func NewPluralMessage

func NewPluralMessage(rules [][]string) (*Message, error)

func (*Message) Clone

func (m *Message) Clone() *Message

func (*Message) Display

func (m *Message) Display(args ...any) string

Display 格式化显示消息翻译文本

  • 对于普通消息, 支持fmt格式化占位符, 如消息文本无自定义格式化占位符, 但T函数传递了多余的附加参数,则直接使用fmt.Sprint拼接参数到Text文本后输出
  • 对于复数消息, 支持fmt格式化占位符, 如消息文本无自定义格式化占位符, 但T函数传递了多余的附加参数,则直接丢弃多余的参数
  • 如果格式化失败,则返回空字符串

type PluralMessage

type PluralMessage struct {
	Index uint8         // 参数索引位置,Count参数在T函数附加格式化参数中的索引位置, 例如 [1] 表示第1个参数为Count参数,从1开始计数
	Texts []*PluralText // 复数表达式文本列表,按从低到高进行规则匹配
}

func ParsePluralMessage

func ParsePluralMessage(rules [][]string) (*PluralMessage, error)

ParsePluralMessage 格式化及检查校验复数消息表达式

  • rules := [][]string{ {`countRule`,`msgText`}... }
  • JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
  • JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]

func (*PluralMessage) Clone

func (p *PluralMessage) Clone() *PluralMessage

Clone 复制复数消息表达式

func (*PluralMessage) Display

func (p *PluralMessage) Display(args ...any) string

Display 格式化显示复数消息翻译文本

  • 依据Index索引位置从args中获取Count参数值
  • 然后与复数表达式列表中的CompareVal进行比较,匹配则返回格式化后的翻译文本
  • 如果未匹配到任何复数表达式,则返回空字符串
  • 对于复数消息, 支持fmt格式化占位符, 如消息文本无自定义格式化占位符, 但T函数传递了多余的附加参数,则直接丢弃多余的参数

func (*PluralMessage) ToStringSlices

func (p *PluralMessage) ToStringSlices() [][]string

ToStringSlices 获取字符串切片配置化结构,通常用于TOML/YAML/JSON序列化/反序列化

type PluralText

type PluralText struct {
	Rules    []*CompareRule
	HasCount bool   // Text 文本中是否含有Count变量的占位符,如不含有则会将args中的Count参数剔除后再对Text行格式化输出
	Text     string // Text 复数翻译文本
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL