dongpan2788 2015-05-20 17:32
浏览 125
已采纳

如何访问接口属性

It was my intention to use the HTTP status codes both in the header and the body of the two response structs. Bu that without setting the status code twice as function parameter and again for the struct to avoid redundancy.

The parameter response of JSON() is an interface to allow both structs to be accepted. The compiler throws the following exception:

response.Status undefined (type interface {} has no field or method Status)

because the response field must not have a status attribute. Is there an alternative way to avoid setting the status code twice?

type Response struct {
    Status int         `json:"status"`
    Data   interface{} `json:"data"`
}

type ErrorResponse struct {
    Status int      `json:"status"`
    Errors []string `json:"errors"`
}

func JSON(rw http.ResponseWriter, response interface{}) {
    payload, _ := json.MarshalIndent(response, "", "    ")
    rw.WriteHeader(response.Status)
    ...
}
  • 写回答

2条回答 默认 最新

  • douguanya4248 2015-05-20 17:41
    关注

    The type response in rw.WriteHeader(response.Status) is interface{}. In Go, you need to explicitly assert the type of the underlying struct and then access the field:

    func JSON(rw http.ResponseWriter, response interface{}) {
        payload, _ := json.MarshalIndent(response, "", "    ")
        switch r := response.(type) {
        case ErrorResponse:
            rw.WriteHeader(r.Status)
        case Response:
            rw.WriteHeader(r.Status) 
        }
        ...
    }
    

    A better and the preferred way to do this however is to define a common interface for your responses, that has a method for getting the status of the response:

    type Statuser interface {
        Status() int
    }
    
    // You need to rename the fields to avoid name collision.
    func (r Response) Status() int { return r.ResStatus }
    func (r ErrorResponse) Status() int { return r.ResStatus }
    
    func JSON(rw http.ResponseWriter, response Statuser) {
        payload, _ := json.MarshalIndent(response, "", "    ")
        rw.WriteHeader(response.Status())
        ...
    }
    

    And it's better to rename Response to DataResponse and ResponseInterface to Response, IMO.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?