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() 函数。

    • 相关阅读:
      从Android APP里面打开其他应用
      jQuery 中 serialize() 方法会受到asp.net 页面影响
      javascript 对象转换 json 的插件
      MVC 4将jQuery升级到1.9出现各种问题。。。
      用MVC做可拖拽的留言板,利用 Jquery模板 JsRender
      未能加载文件或程序集“Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”
      处理MVC中默认的Json方法返回时间的问题
      jQuery 中使用$.post 无法获取 json
      MVC中用 BundleCollection 压缩CSS时图片路径问题
      MVC中返回Json的几种声明方式
    • 原文地址:https://www.cnblogs.com/liuqun/p/13622300.html
    Copyright © 2011-2022 走看看