【问题标题】:Can functions implement an interface in Go函数可以在 Go 中实现接口吗
【发布时间】:2018-05-10 14:22:44
【问题描述】:

我正在尝试制作一个类似于http.Handler 的界面。对于我的 API 的某些端点,我需要在查询中包含一个 APNS 令牌,或者我需要回复 http.StatusBadRequest

我想让DeviceHandlerFunc类型实现ServeHTTP(http.ResponseWriter, *http.Request)并自动解析token并用token调用自己:

type DeviceHandlerFunc func(http.ResponseWriter, *http.Request, string)

func (f DeviceHandlerFunc) ServeHTTP(res http.ResponseWriter, req *http.Request) {
    token := req.URL.Query().Get("token")

    if token == "" {
        http.Error(res, "token missing from query", http.StatusBadRequest)
    } else {
        f(res, req, token)
    }
}

然后来自main.go

func main() {
    mux := http.NewServeMux()
    mux.Handle("/", getDevice)
    log.Fatal(http.ListenAndServe(":8081", mux))
}

func getDevice(res http.ResponseWriter, req *http.Request, token string) {
    // Do stuff with token...
}

这会导致编译器错误:

main.go:22:13: cannot use getDevice (type func(http.ResponseWriter, *http.Request, string)) as type http.Handler in argument to mux.Handle:
    func(http.ResponseWriter, *http.Request, string) does not implement http.Handler (missing ServeHTTP method)

在我看来,func(http.ResponseWriter, *http.Request, string) 类型实现了http.Handler,这一点我再清楚不过了。我做错了什么?

示例代码as playground

【问题讨论】:

    标签: function go interface


    【解决方案1】:

    您的DeviceHandlerFunc 类型确实实现了http.Handler。这不是问题。

    但是您的getDevice() 函数不是属于DeviceHandlerFunc 类型,它属于func(http.ResponseWriter, *http.Request, string) 类型(这是一个未命名的类型,显然没有实现http.Handler)。

    要使其工作,请使用简单类型conversion

    mux.Handle("/", DeviceHandlerFunc(getDevice))
    

    您可以将getDevice 转换为DeviceHandlerFunc,因为DeviceHandlerFunc 的基础类型与getDevice 的类型相同。在Go Playground 上试试吧。

    以下方法也可以:

    var f DeviceHandlerFunc = getDevice
    mux.Handle("/", f)
    

    这里f 的类型显然是DeviceHandlerFunc。您可以将getDevice 分配给f,因为assignability 规则适用,即这个:

    [在任何这些情况下,x 的值可分配给T 类型的变量(“x 可分配给T”):]

    • x 的类型 VT 具有相同的底层类型,并且 VT 中的至少一个不是已定义的类型。

    【讨论】:

      猜你喜欢
      • 2012-09-28
      • 2018-04-16
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 2015-02-05
      • 1970-01-01
      相关资源
      最近更新 更多