实现思路
- 定义错误结构体:定义一个包含错误码和错误信息占位符的自定义错误结构体。
- 使用翻译库:借助如
go-i18n
等翻译库来实现多语言支持。这些库通常使用翻译文件(如 .mo
、.json
等格式)存储不同语言的翻译文本。
- 设置语言环境:通过某种方式(如HTTP请求头、系统环境变量等)确定当前语言环境,并据此选择对应的翻译文本。
关键代码示例
package main
import (
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/nicksnyder/go-i18n/v2/goi18n"
"golang.org/x/text/language"
)
// BusinessLogicError 自定义业务逻辑错误类型
type BusinessLogicError struct {
Code int
// 这里可根据实际情况添加更多属性
}
func (e BusinessLogicError) Error() string {
// 此方法在没有翻译时提供默认错误表示
return fmt.Sprintf("BusinessLogicError: code %d", e.Code)
}
// 假设以下是库存不足错误码
const ErrOutOfStockCode = 1001
// 加载翻译器
func setupTranslator(lang string) (*goi18n.Bundle, *i18n.Localizer) {
bundle := goi18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", goi18n.UnmarshalJSON)
var err error
switch lang {
case "zh":
_, err = bundle.LoadMessageFileBytes([]byte(`{
"id": "out_of_stock",
"translation": "库存不足"
}`))
case "en":
_, err = bundle.LoadMessageFileBytes([]byte(`{
"id": "out_of_stock",
"translation": "Out of stock"
}`))
default:
_, err = bundle.LoadMessageFileBytes([]byte(`{
"id": "out_of_stock",
"translation": "Out of stock"
}`))
}
if err != nil {
panic(err)
}
localizer := i18n.NewLocalizer(bundle, lang)
return bundle, localizer
}
func getErrorMsg(err error, lang string) string {
if businessErr, ok := err.(BusinessLogicError); ok {
if businessErr.Code == ErrOutOfStockCode {
bundle, localizer := setupTranslator(lang)
msg, _ := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "out_of_stock",
})
return msg
}
}
return err.Error()
}
多语言错误信息管理与维护
- 集中管理翻译文件:将所有语言的翻译文本集中存储在特定目录下,如
locales
。每种语言对应一个文件,便于维护和扩展。
- 自动化工具:使用工具生成和更新翻译文件。例如,在代码中标记需要翻译的字符串,然后通过工具提取并更新到翻译文件中。
- 版本控制:将翻译文件纳入版本控制系统(如Git),以便跟踪修改历史,多人协作时也能方便合并和管理。