我使用Martini库编写了一个非常简单的Go应用程序。在组合一个简单的REST API示例时,我想在发生错误时将JSON数据呈现给用户,如:
{
error: "Document Not Found",
code: 404
}
我正在使用以下代码返回Martini可以渲染为JSON的地图。 包ErrorResponces
import "net/http"
type ErrJson interface {
RenderErr(v int)
}
func RenderErr(v int) map [string]interface{} {
var returnMap = map[string]interface{} {
"error": http.StatusText(v),
"code": v,
}
return returnMap
}
稍后在我的控制器代码中,我尝试使用
测试此方法fmt.Println(ErrJson.RenderErr(400))
但是我收到以下错误:
controllers \ FoodController.go:25:不能使用400(类型int)作为类型 函数参数中的ErrorResponces.ErrJson: int没有实现ErrorResponces.ErrJson(缺少RenderErr方法)
controllers \ FoodController.go:25:调用时没有足够的参数 ErrorResponces.ErrJson.RenderErr controllers \ FoodController.go:25: ErrorResponces.ErrJson.RenderErr(400)用作值
我很难弄清楚这个错误正在谈论什么。
答案 0 :(得分:2)
您似乎试图直接在接口类型上调用函数,而不是实现该接口的对象。
这是一个返回JSON数据的简单示例:
package main
import (
"encoding/json"
"github.com/codegangsta/martini"
"net/http"
)
func Encode(v ...interface{}) (string, error) {
var data interface{} = v
if v == nil {
// So that empty results produces `[]` and not `null`
data = []interface{}{}
} else if len(v) == 1 {
data = v[0]
}
b, err := json.Marshal(data)
return string(b), err
}
func RenderErr(v int) map[string]interface{} {
var returnMap = map[string]interface{}{
"error": http.StatusText(v),
"code": v,
}
return returnMap
}
func main() {
m := martini.Classic()
m.Get("/", func(c martini.Context, w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/json")
str, err := Encode(RenderErr(400))
if err != nil {
panic(err)
}
return str
})
m.Run()
}
如果你想使用你的界面想法,你可以做这样的事情(我试图复制你基本上做的事情):
package main
import (
"encoding/json"
"github.com/codegangsta/martini"
"net/http"
)
func Encode(v ...interface{}) (string, error) {
var data interface{} = v
if v == nil {
// So that empty results produces `[]` and not `null`
data = []interface{}{}
} else if len(v) == 1 {
data = v[0]
}
b, err := json.Marshal(data)
return string(b), err
}
type ErrJson interface {
RenderErr() string
}
type ErrJsonCode int
func (e ErrJsonCode) RenderErr() string {
var returnMap = map[string]interface{}{
"error": http.StatusText(int(e)),
"code": int(e),
}
str, err := Encode(returnMap)
if err != nil {
panic(err)
}
return str
}
func main() {
m := martini.Classic()
m.Get("/", func(c martini.Context, w http.ResponseWriter, r *http.Request) string {
w.Header().Set("Content-Type", "application/json")
return ErrJsonCode(400).RenderErr()
})
m.Run()
}
我不确定我会这样设计它。我可能会使它更通用,并且它支持多种内容类型,并且没有与其内容类型相关的错误。以下是关于使用Martini构建一个restful API的好文章:http://0value.com/build-a-restful-API-with-Martini(它使用了一些高级概念)。