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

王先生:

当检查下面的代码时,对从函数到接口的类型转换有疑问。


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:不能在faAdd的参数中使用fa(AdderFunc类型)作为Adder类型:AdderFunc没有实现Adder(缺少add方法)


问题

  1. http.HandlerFunc(helloHandler)得到type的值http.Handler,因为这是http.Handle()期望值,对吗?
  2. 如果是,则意味着它将函数转换为接口类型的值,这是怎么发生的?
    • 这是go的内置功能吗?
      我做了一个测试(func_to_intf.go如上),似乎没有。
    • 还是http.HandlerFunc通过特殊的实现来实现?

@Update-摘要

(尽管答案很好地解决了这些问题,但是在进行了更多的测试和更多测试之后,还需要其他一些功能来完全消除最初的疑问,如下所示。)

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

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

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

此外,代码可以定义自定义类型的方法,无论它是什么基础类型,无论它是struct不是。在这种情况下,httpServeHTTP在其上定义方法,当然,它只是调用函数本身。

您可以在此处阅读源代码: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)
}

游乐场:https : //play.golang.org/p/5mf_afHLQA2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将二维地图从Firestore转换为Typescripts接口类型

Typescript将未知类型转换为接口类型

将具体的实现类型转换为通用接口类型

无法将实例类型转换为实例实现接口的接口类型

如何将接口转换为具体类型

如何将接口转换为自定义类型

如何将接口{}转换为其基础类型

如何将导出的函数转换为函数类型?

无效的类型断言:无法将os.Stdout转换为接口类型io.ReadWriter?

使用C#和反射将接口类型转换为具体类型

将继承类型的对象列表转换为新的接口类型列表

Typescript接口类型值转换为联合类型

如何将接口转换为结构

将使用URLClassLoader创建的对象转换为接口类型

在VBA中强制转换为接口类型

Swift:从接口类型数组转换为对象数组崩溃

将字节数组解组到接口,然后将该接口类型强制转换为struct不起作用?

如何将转换转换为函数?

无法将类型为“ System .__ ComObject”的COM对象转换为接口类型为“ EnvDTE.Project”

无法将类型为“ System .__ ComObject”的COM对象转换为接口类型为“ Microsoft.Office.Interop.Excel.Worksheets”

SAP:无法将“System.__ComObject”类型的 COM 对象转换为接口类型“sapfewse.GuiTextField”

如何将一种类型的对象(接口)转换为另一种类型(接口)?

将接口类型的集合传递给函数

如何将接口{}转换为* rsa.PublicKey golang类型

如何将 es6 箭头函数参数替换为自定义类型(接口)?

如何将类型转换为值

函数之间如何处理接口类型?

如何将向量转换为函数

关闭无法隐式转换为通用接口类型的成员的通用接口的类的实例