如何访问接口的属性

时间:2015-05-20 17:32:45

标签: interface go

我打算在两个响应结构的标题和正文中使用HTTP状态代码。不要将状态代码设置为两次作为函数参数,再次为结构避免冗余。

response的参数JSON()是允许接受两个结构的接口。编译器抛出以下异常:

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

因为响应字段不能具有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)
    ...
}

2 个答案:

答案 0 :(得分:4)

rw.WriteHeader(response.Status)中的interface{}类型为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) } ... } 。在Go中,您需要显式断言底层结构的类型,然后访问该字段:

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

最好将DataResponse重命名为ResponseInterface,将Response重命名为{{1}},IMO。

答案 1 :(得分:1)

接口没有属性,因此您需要从接口中提取结构。为此,请使用type assertion

if response, ok := response.(ErrorResponse); ok {
    rw.WriteHeader(response.Status)
    ...