错误码到本地化提示的映射必须解耦语言与业务逻辑,采用嵌套map按locale动态加载资源,标准化bcp 47语言标识,支持fallback机制,并通过getlocalizedmessage函数安全容错处理未定义错误码。

错误码字符串到本地化提示的映射必须解耦语言与业务逻辑
硬编码 "ERR_USER_NOT_FOUND" → "用户不存在" 这类映射会迅速失控:新增语言要改代码、翻译漏项难发现、测试覆盖成本高。核心原则是把错误码当 key,把多语言文案当资源数据,运行时按 locale 动态加载对应资源包。
用 map[string]map[string]string 实现轻量级多语言映射表
不依赖外部 i18n 框架时,最直接的方式是构造嵌套 map:外层 key 是错误码,内层 key 是语言标识(如 "zh-CN"、"en-US"),值为提示文本。注意以下实操细节:
-
map初始化必须在包级变量或初始化函数中完成,避免每次调用都重建; - 语言 key 统一用 BCP 47 标准(如
"zh"、"zh-Hans"、"en"),不要用"ch"或"cn"这类非标缩写; - 缺失语言时应 fallback 到默认语言(通常是
"en"),而非 panic 或返回空字符串; - 错误码 key 必须全大写 + 下划线,和后端/协议保持一致,避免
"userNotFound"和"USER_NOT_FOUND"混用。
var ErrMsgMap = map[string]map[string]string{
"ERR_USER_NOT_FOUND": {
"zh-CN": "用户不存在",
"en-US": "User not found",
},
"ERR_INVALID_TOKEN": {
"zh-CN": "令牌无效",
"en-US": "Invalid token",
},
}
从 http.Request.Header.Accept-Language 提取 locale 并做标准化
客户端传来的 Accept-Language 是个逗号分隔的带权重列表(如 "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"),不能直接当 key 用。需解析、截取主标签、并匹配已支持的语言集:
- 用
strings.Split()拆分后,对每个片段取strings.TrimSpace()再按";"分割,提取语言部分; - 只取第一个
-前的部分作为基础语言(如"zh-CN"→"zh"),便于 fallback; - 检查该语言是否在预设支持列表中(
[]string{"zh", "en", "ja"}),否则降级到"en"; - 避免直接使用
http.CanonicalHeaderKey("accept-language"),它只规范 header 名,不处理值。
封装 GetLocalizedMessage 函数并处理未定义错误码
暴露一个纯函数,输入 error code 和 locale,输出提示字符串。关键点在于容错:
- 若错误码不在
ErrMsgMap中,返回兜底文案(如"未知错误"),而不是 panic; - 若 locale 对应文案为空,尝试 fallback 到基础语言(
"zh-CN"→"zh"),再 fallback 到"en"; - 函数签名建议为
func GetLocalizedMessage(code, locale string) string,不接收 context 或 request,保持可测试性; - 不要在函数里做 HTTP header 解析——那是 handler 层的事,本函数只做“查表+fallback”。
真正容易被忽略的是错误码生命周期管理:新接口上线时,前端可能传入服务端尚未配置的错误码,此时返回空或 panic 都比返回错误文案更危险。必须确保未定义错误码有明确、安全的默认行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











