gpt4 book ai didi

go - HandlerFunc(f) 如何将函数转换为接口(interface)类型?

转载 作者:IT王子 更新时间:2023-10-29 02:27:04 26 4
gpt4 key购买 nike

检查以下代码时,对从函数到接口(interface)的类型转换有疑问。


代码

http_hello.go:

package main

import (
"fmt"
"log"
"net/http"
)

// hello http,
func helloHttp() {
// register handler,
http.Handle("/", http.HandlerFunc(helloHandler))

// start server,
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}

}

// handler function - hello,
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
}

func main() {
helloHttp()
}

上面的代码有效。

(然后我尝试编写一个小程序来检查这是一个通用功能,但它不起作用,请检查以下代码)

func_to_intf.go:

package main

import (
"fmt"
)

// an interface,
type Adder interface {
add(a, b int) int
}

// alias of a function signature,
type AdderFunc func(int, int) int

// a simple add function,
func simpleAdd(a, b int) int {
return a + b
}

// call Adder interface to perform add,
func doAdd(a, b int, f Adder) int {
return f.add(a, b)
}

func funcToIntf() {
fa := AdderFunc(simpleAdd)
fmt.Printf("%#v, type: %T\n", fa, fa)

a, b := 1, 2
sum := doAdd(a, b, fa)
fmt.Printf("%d + %d = %d\n", a, b, sum)
}

func main() {
funcToIntf()
}

输出:

./func_to_intf.go:30:14: cannot use fa (type AdderFunc) as type Adder in argument to doAdd: AdderFunc does not implement Adder (missing add method)


问题

  1. http.HandlerFunc(helloHandler) 获取类型为 http.Handler 的值,因为这是 http.Handle() 所期望的,是对吗?
  2. 如果是,那么意味着它将函数转换为接口(interface)类型的值,这是如何发生的?
    • 这是go的内置功能吗?
      我做了一个测试(如上面的 func_to_intf.go),但似乎没有。
    • 或者,http.HandlerFunc 的特殊实现实现了吗?

@Update - 总结

(虽然答案很好地解决了问题,但经过审查和更多测试后,还需要其他几个 go 特性来完全消除最初的疑问,如下所示。)

  • 函数类型。
    函数是值,它有类型。
    函数类型可以通过函数签名上的 type 关键字定义。
    例如 type AdderFunc func(int, int) int
  • 函数类型转换器 T(v)
    任何函数都可以转换为具有相同签名的函数类型,只需通过T(v),函数类型名称为T,实际函数为v
    然后当调用新值时,调用实际函数 v
    例如 fa := AdderFunc(simpleAdd)
    (在问这个问题之前,这对我来说很模糊,这是我感到困惑的主要原因之一)

最佳答案

这是一个简单的类型转换。

在 Go 中,除了 struct 之外,您还可以定义自定义类型。在这种情况下,http.HandlerFunc 是一个函数类型,func(http.ResponseWriter,*http.Request)。由于您的函数与自定义类型具有相同的基础类型(签名),因此可以将其转换为自定义类型。

此外,代码可以在自定义类型上定义方法,无论它是什么底层类型,也不管它是否是struct。在这种情况下,http包在其上定义了ServeHTTP方法,当然,它只是调用函数本身。

您可以在这里阅读源代码:https://golang.org/src/net/http/server.go?s=58384:58444#L1936

对于示例代码中的加法器,您可以这样做:在 AdderFunc 上定义一个方法。

func (a AdderFunc) add(x, y int) int {
return a(x, y)
}

Playground :https://play.golang.org/p/5mf_afHLQA2

关于go - HandlerFunc(f) 如何将函数转换为接口(interface)类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51694086/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com