zoukankan      html  css  js  c++  java
  • go type func() 自定义函数类型

    @

    目录

      因看不懂 go 中的自定义函数类型,看了https://www.jianshu.com/p/431abe0d2ed5 理解了不少,特此搬运到自己博客

      在看golang 的http服务部分代码时,被golang 中的 type func()写法难住了,一时没看懂代码。后来查资料后,有了一点理解。
      在golang中可以通过这样简单实现一个http服务

      package main
      
      import "net/http"
      
      func mHttp() {
          http.HandleFunc("/", h)
          http.ListenAndServe("0.0.0.0:8888",nil)
      }
      func h(w http.ResponseWriter, r *http.Request) {
      
      }
      

      http.HandleFunc()是一个注册函数,传一个string类型的路由,和一个函数,函数的参数为(http.ResponseWriter, *http.Request)。跟踪进入函数,在golang 源码net/http/server.go文件中

      func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
          DefaultServeMux.HandleFunc(pattern, handler)
      }
      

      在HandleFunc调用了DefaultServeMux.HandleFunc(pattern, handler)
      至于这些函数是干啥的先不做探讨,这不是本文的重点。
      再次跟进函数

      func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
          if handler == nil {
              panic("http: nil handler")
          }
          mux.Handle(pattern, HandlerFunc(handler))
      }
      

      在mux.Handle(pattern, HandlerFunc(handler)) 的第二个参数HandlerFunc(handler)是什么鬼。
      跟进看一下

      type HandlerFunc func(ResponseWriter, *Request)
      
      func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
          f(w, r)
      }
      

      原来HandlerFunc 是用 type 定义的函数,而函数的类型就是最开始传入的类型
      func(ResponseWriter, *Request)
      ServeHTTP是HandlerFunc的一个方法(注意一下,golang中方法和函数不是一回事)。并且HandlerFunc实现了 Handler接口
      Handler接口定义:

      type Handler interface {
          ServeHTTP(ResponseWriter, *Request)
      }
      

      回到HandleFunc方法中,mux.Handle(pattern, HandlerFunc(handler))的第二个参数是把传入的函数 handler 强转成 HandlerFunc类型,这样handler就实现了Handler接口。
      到这我们明白HandlerFunc(handler) 是把普通函数强转成type定义的函数。
      现在写一个简单的demo验证一下:

      package main
      
      import "fmt"
      
      func main() {
      	one(2,callback)
      }
      
      //需要传递函数
      func callback(i int) {
      	fmt.Println("i am callBack")
      	fmt.Println(i)
      }
      
      //main 中调用的函数
      func one(i int,f func(int)) {
      	two(i,fun(f))
      }
      
      //one() 中调用的函数
      func two(i int, c Call) {
      	c.call(i)
      }
      //定义的type函数
      type fun func(int)
      
      //fun实现的Call接口的call()函数
      func (f fun) call(i int) {
      	f(i)
      }
      
      //接口
      type Call interface {
      	call(int)
      }
      

      先看一下程序的运行结果:
      在这里插入图片描述
      我们在main()函数中调用了one()函数,并传入了callback()函数,最终调用了我们传入的callback()函数。
      理一下思路:
      使用type定义函数 func(int)
      定义 Call 接口,Call中有一个函数 call(int)
      在main()中调用one(2, callback),在one()中调用two(),传入two()函数前,对callback函数实现了类型转换,从普通函数转换成type定义的函数。
      在 two() 中调用传入的 c 因为 c 实现了 Call 接口,所以可以调用 call() 函数,最终调用了我们传入的 callback() 函数。

    • 相关阅读:
      es5预览本地文件、es6练习代码演示案例
      Java实现 LeetCode 838 推多米诺(暴力模拟)
      Java实现 LeetCode 838 推多米诺(暴力模拟)
      Java实现 LeetCode 838 推多米诺(暴力模拟)
      Java实现 LeetCode 837 新21点(DP)
      Java实现 LeetCode 837 新21点(DP)
      Java实现 LeetCode 837 新21点(DP)
      Java实现 LeetCode 836 矩形重叠(暴力)
      Subversion under Linux [Reprint]
      Subversion how[Reprint]
    • 原文地址:https://www.cnblogs.com/liuqun/p/13622300.html
    Copyright © 2011-2022 走看看