dsour68888 2013-12-21 05:41
浏览 62
已采纳

Go界面方法的用法

I have written a very simple Go app using the Martini library. When putting together a simple REST API example I wanted to render JSON data back to the user when an error occurred like:

{
    error: "Document Not Found",
    code: 404
}

I'm using the following code to return a map that Martini can render into JSON. package 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

}

Later in my controller code I try and test this method using

fmt.Println(ErrJson.RenderErr(400))

However I get the following error:

controllers\FoodController.go:25: cannot use 400 (type int) as type ErrorResponces.ErrJson in function argument: int does not implement ErrorResponces.ErrJson (missing RenderErr method)

controllers\FoodController.go:25: not enough arguments in call to ErrorResponces.ErrJson.RenderErr controllers\FoodController.go:25: ErrorResponces.ErrJson.RenderErr(400) used as value

I'm having a hard time figuring out exactly what this error is talking about.

  • 写回答

1条回答 默认 最新

  • dqx36753 2013-12-21 07:01
    关注

    It seems that you're trying to called a function directly on an interface type instead of an object which implements that interface.

    Here's a simple example that returns JSON data:

    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()
    }
    

    If you wanted to use your interface idea, you could do something like this (I tried to copy what you were basically doing):

    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()
    }
    

    I'm not sure I would design it like this though. I would probably make it more generic and have it support multiple content types, and not have an error tied to its content type. Here is a decent article about building a restful API with Martini: http://0value.com/build-a-restful-API-with-Martini (it uses some advanced concepts).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序