推荐优先使用 deepl api:设 authorization 头、url 编码 text、解析 translations 数组中 text 字段;百度需签名与 token 管理;用 flag 解析参数、http.client 设超时与简单重试。

怎么用 Go 调通一个翻译 API(比如 DeepL 或百度翻译)
Go 本身没有内置翻译能力,得靠 HTTP 请求调第三方 API。关键不是“能不能写”,而是选哪个服务、怎么构造请求、怎么处理响应体里的 text 字段——很多人卡在返回 JSON 解析失败或 403 Forbidden 上。
推荐优先试 DeepL API:免费额度够小项目用,响应结构干净,没中文乱码风险;百度翻译要签名 + access_token 过期轮换,新手容易栽在 sign 计算上。
- 用
net/http发 POST,别用http.Get—— 翻译接口基本都要Content-Type: application/x-www-form-urlencoded或application/json - DeepL 的
text参数必须是 URL 编码后的字符串,直接传中文会 400;百度则要求先url.QueryEscape再拼进form - 记得设
req.Header.Set("Authorization", "DeepL-Auth-Key YOUR_KEY"),漏掉这行就是403
JSON 解析失败?检查字段名大小写和嵌套层级
DeepL 返回的 JSON 是 {"translations":[{"detected_source_language":"ZH","text":"Hello"}]},而百度是 {"trans_result":[{"src":"你好","dst":"Hello"}]}。Go 的 json.Unmarshal 对字段名大小写敏感,且结构体字段必须导出(首字母大写)。
常见错误:json: cannot unmarshal object into Go struct field .text of type string——其实是把顶层 translations 数组当成了单个对象。
立即学习“go语言免费学习笔记(深入)”;
- 定义结构体时,用
json:"translations"显式绑定,别依赖默认命名规则 - DeepL 的
text在数组里,必须先解出[]struct{Text string `json:"text"`},再取[0].Text - 百度响应里可能有
error_code字段,别急着解析trans_result,先检查error_code == 0
命令行参数怎么接?别手写 os.Args 解析
os.Args 容易漏掉空格、引号、编码问题,比如输入 ./trans "你好世界",实际拿到的是 ["./trans", "\"你好世界\""]。用标准库 flag 更稳。
翻译场景下,至少要支持源语言、目标语言、文本三要素。DeepL 支持 source_lang=ZH 和 target_lang=EN,但自动检测更省事——所以命令行参数设计成可选。
- 用
flag.String("t", "EN", "target language"),默认 EN,用户输-t JA就切日语 - 文本参数放最后,用
flag.Args()拿剩余部分,strings.Join(flag.Args(), " ")合并防断句 - 别忘了
flag.Parse()必须在所有flag.Xxx之后、读参数之前调用,否则全是空值
HTTP 超时和重试不能省,翻译 API 响应不稳定
DeepL 国内直连偶尔超时,百度有时返回 502。Go 默认 HTTP client 没设超时,一次卡死就整个命令卡住。
不用引入第三方重试库,原生 net/http 配合简单 for 循环就行,重点是控制重试次数和间隔。
- 创建 client 时设
&http.Client{Timeout: 10 * time.Second},避免等 60 秒才报错 - 最多重试 2 次,每次间隔
time.Second,用time.Sleep控制,别用固定time.Sleep(1e9)(单位是纳秒) - 只对
context.DeadlineExceeded和5xx错误重试,400类错误重试也没用
翻译这事,最难的不是发请求,是把用户随手敲的一句话,准确塞进 API 规定的字段里,再从嵌套 JSON 里干净地掏出来——中间任何一环大小写、编码、超时没对上,结果就变成空字符串或者 panic。多打两次 fmt.Printf("%+v", resp) 比查文档快。










