如何访问接口的属性

use*_*268 0 interface go

我的目的是在两个响应结构的标头和正文中使用 HTTP 状态代码。但是,无需将状态代码设置两次作为函数参数,并再次设置结构以避免冗余。

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

response.Status undefined (type interface {} has no field or method Status)
Run Code Online (Sandbox Code Playgroud)

因为响应字段不能有状态属性。有没有其他方法可以避免设置状态代码两次?

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)
    ...
}
Run Code Online (Sandbox Code Playgroud)

Soh*_*neh 5

response中的类型rw.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) 
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

然而,更好且首选的方法是为响应定义一个通用接口,它有一个获取响应状态的方法:

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())
    ...
}
Run Code Online (Sandbox Code Playgroud)

在我看来,最好将其重命名ResponseDataResponse和。ResponseInterfaceResponse