一尘不染

如何访问接口属性

go

我打算在两个响应结构的标头和主体中同时使用HTTP状态代码。不要在没有设置状态码的情况下将其设置为功能参数的两倍,并再次为结构设置以避免冗余。

该参数responseJSON()是允许两个结构被接受的接口。编译器将引发以下异常:

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

因为响应字段必须没有状态属性。是否有另一种方法可以避免两次设置状态代码?

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

阅读 348

收藏
2020-07-02

共1个答案

一尘不染

键入responserw.WriteHeader(response.Status)interface{}。在Go中,您需要显式声明基础结构的类型,然后访问该字段:

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

但是,更好的方法是为响应定义一个通用接口,该接口具有一种获取响应状态的方法:

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

而且最好重新命名Response,以DataResponseResponseInterfaceResponse,IMO。

2020-07-02