
go 中使用 gorilla json-rpc 时,若响应结构体字段为小写(未导出),json 包无法序列化它们,导致 "result": {} 空对象——只需将字段首字母大写即可解决。
go 中使用 gorilla json-rpc 时,若响应结构体字段为小写(未导出),json 包无法序列化它们,导致 "result": {} 空对象——只需将字段首字母大写即可解决。
在 Go 的 JSON-RPC 实现(如 Gorilla Toolkit 的 gorilla/rpc)中,服务端返回的响应需经 json.Marshal() 序列化为 JSON。而 Go 的 encoding/json 包仅能序列化导出(exported)字段——即首字母大写的字段。若结构体字段为小写(如 sum、message),即使赋值成功,序列化结果中也不会包含这些字段,最终 result 变为一个空 JSON 对象 {}。
✅ 正确写法:确保响应结构体字段导出
type Args struct {
A, B int `json:"a,b"` // 参数字段也建议导出(可选,但推荐)
}
type Response struct {
Sum int `json:"sum"` // ✅ 首字母大写 + 显式 json tag(更可控)
Message string `json:"message"` // ✅ 同上
}
type Arith int
func (t *Arith) Add(r *http.Request, args *Args, reply *Response) error {
reply.Sum = args.A + args.B
reply.Message = "Do math"
return nil
}此时,对请求:
{"method":"Arith.Add","params":[{"A":10,"B":2}],"id":1}将正确返回:
{
"result": {"sum": 12, "message": "Do math"},
"error": null,
"id": 1
}⚠️ 注意事项
- 导出性是硬性要求:json 包不关心字段是否有 json tag,首要条件是字段必须可导出(public)。sum 和 message 是私有字段,永远无法被序列化。
- *`string有效的原因**:string` 是基础类型,其值本身可直接序列化;而结构体依赖字段导出性,二者机制不同。
- 推荐显式添加 json tag:避免因 Go 字段名与 JSON 键不一致引发歧义(例如 Sum → "sum"),提升可维护性。
- 方法签名须匹配 Gorilla RPC 规范:第三个参数必须为指针类型(*Response),且方法需为导出方法(接收者类型 Arith 为导出类型,方法名 Add 首字母大写)。
? 快速自查清单
- [ ] 响应结构体字段名首字母是否大写?
- [ ] 是否遗漏了 json tag?(非必需但强烈推荐)
- [ ] RPC 方法名是否以大写字母开头?
- [ ] 接收者类型(如 Arith)是否为导出类型?
修复导出性后,Gorilla JSON-RPC 即可正常序列化结构体响应——这是 Go 语言反射与 JSON 编码机制决定的基础约束,而非框架 Bug。










