
本文详解使用 gorest 框架时 post 方法中参数引用错误的典型问题,指出 `undefined: user` 编译错误的根本原因在于混淆了类型名与参数名,并提供修正后的完整可运行代码及关键注意事项。
在基于 gorest 的 Go REST 服务开发中,定义 POST 接口时需特别注意方法签名与结构体参数的匹配逻辑。原始代码中存在两个关键错误:
- 参数类型未定义:func (serv HelloService) Posted(posted User) 中的 User 并非已声明的类型——实际定义的结构体名为 Invitation,其字段 User String 是成员而非独立类型;
- 参数引用错误:方法体内写成 fmt.Println(User),但 User 是字段名或类型名,而非函数参数;正确做法是访问传入的参数变量 posted(或按需重命名)。
✅ 正确写法如下(已修复所有问题):
package main import ( "code.google.com/p/gorest" "fmt" "net/http" ) // 定义数据承载结构体(注意:字段首字母大写以导出) type Invitation struct { User string `json:"user"` // 建议添加 json tag 便于解析 } // REST 服务定义 type HelloService struct { gorest.RestService HelloWorld gorest.EndPoint `method:"GET" path:"/hello-world/" output:"string"` SayHello gorest.EndPoint `method:"GET" path:"/hello/{name:string}" output:"string"` Posted gorest.EndPoint `method:"POST" path:"/post/" postdata:"Invitation"` // 关键:postdata 应指向结构体名 } func main() { gorest.RegisterService(new(HelloService)) http.Handle("/", gorest.Handle()) fmt.Println("Server starting on :8787...") http.ListenAndServe(":8787", nil) } // POST 处理方法:参数名必须与 postdata 标签值一致(此处为 Invitation),且使用参数变量而非类型名 func (serv HelloService) Posted(invitation Invitation) { fmt.Printf("Received POST data: %+vn", invitation) // 可进一步处理 invitation.User } func (serv HelloService) HelloWorld() string { return "Hello World" } func (serv HelloService) SayHello(name string) string { return "Hello " + name }
? 关键注意事项:
- postdata:”Invitation” 必须与结构体名称(首字母大写)完全一致,gorest 会自动将请求体反序列化为该类型;
- 方法参数名(如 invitation)是变量标识符,不可写作类型名 Invitation 或字段名 User;
- 所有需被 gorest 自动绑定的结构体字段必须首字母大写(即导出);
- gorest 已停止维护(原仓库 code.google.com/p/gorest 已不可用),生产环境强烈推荐迁移到现代框架,如 gin、echo 或标准库 net/http + encoding/json 组合。
? 测试方式(使用 curl):
curl -X POST http://localhost:8787/post/ -H "Content-Type: application/json" -d '{"user":"alice"}'
输出示例:
Received POST data: {User:"alice"}
通过规范参数命名、明确类型引用与结构体绑定关系,即可彻底解决 undefined: User 类编译错误,并构建健壮的 Go REST 接口。