【发布时间】:2017-07-17 10:58:55
【问题描述】:
仍然是 Golang 初学者,我正在尝试编写一个通用函数来服务 ReST 请求。我传递了一个函数来创建一个新资源(结构),并在其上实现了一个接口,因为我还将调用结构上的方法。解码 JSON 时,记录类型显示正确的(结构)类型,但 JSON 解码器似乎只识别接口,它无法解码。
package main
import (
"encoding/json"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
"strings"
)
// general resource interface
type resource interface {
// check semantics and return an array of errors or nil if no error found
check() []string
// update the resource in backend
update() error
}
// specific resource named "anchor"
type anchor struct {
ID string `json:"id"`
Name string `json:"name"`
}
func newAnchor() resource {
return anchor{}
}
func (a anchor) check() []string {
return nil
}
func (a anchor) update() error {
return nil
}
// generic function to create (POST) a new resource
func restCreate(newResource func() resource) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
const F = "restCreate"
var checkErrs []string
res := newResource()
log.Printf("%s res type %T\n", F, res)
dcdr := json.NewDecoder(r.Body)
err := dcdr.Decode(&res)
log.Printf("%s Unmarshalled into %T: %+v\n", F, res, res)
if err == nil {
checkErrs = res.check()
}
switch {
case err != nil:
w.WriteHeader(http.StatusInternalServerError)
log.Printf("[ERR] %s: %v\n", F, err)
case checkErrs != nil:
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(strings.Join(checkErrs, "\n")))
log.Printf("%s: %v\n", F, err)
default:
res.update()
bs, _ := json.Marshal(res)
w.Write(bs)
}
}
}
func main() {
r := httprouter.New()
r.POST("/anchors", restCreate(newAnchor))
http.ListenAndServe(":8080", r)
}
执行日志显示:
restCreate res type main.anchor
restCreate 解组到 main.anchor: {ID: Name:}
[ERR] restCreate: json: 无法将对象解组为 main.resource
为什么 Printf 显示结构类型而 json.Decoder 显示接口?
我会很感激任何关于出了什么问题以及如何以通用方式解决这个问题的指标......
【问题讨论】: