Golang 函数作为类型

package main

import (
	"fmt"
)

type Student interface {
	say()
}

func (f FuncA) say() {
	fmt.Println(f(1, 2))
}

type FuncA func(a, b int) int

func add(a, b int) int {
	return a + b
}

func div(a, b int) int {
	return a + b
}

func main() {
	a := FuncA(add)
	fmt.Printf("%T,%d\n", a, a(1, 2))
	a.say()

	d := FuncA(div)
	fmt.Printf("%T,%d\n", d, d(6, 2))
	d.say()

	fmt.Println("---------分割线---------")

	var stu Student
	stu = a
	stu.say()

	stu = d
	stu.say()

}

输出:

 解释:

FuncA 是一种函数类型,它的函数定义是func(a, b int) int。

然后add和div的函数定义与FuncA的一样的,所以可以将add和div的强转成FuncA。即:

a := FuncA(add)

因为FuncA,它拥有say()方法,那么 a和d都会拥有say()方法。同时因为Student中也有say()方法,含义定义且与FuncA一致,所以FuncA也实现了Student,同理a和d也实现了Student。所以a和d都可以赋值给Student变量,这也叫多态。

HTTP包中的例子

HTTP 包中包含有 Handler 接口定义,代码如下:

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

Handler 用于定义每个 HTTP 的请求和响应的处理过程。

同时,也可以使用处理函数实现接口,定义如下:

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

要使用闭包(匿名函数)实现默认的 HTTP 请求处理,可以使用 http.HandleFunc() 函数,函数定义如下:

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

而 DefaultServeMux 是 ServeMux 结构,拥有 HandleFunc() 方法,定义如下:

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    mux.Handle(pattern, HandlerFunc(handler))
}

上面代码将外部传入的函数 handler() 转为 HandlerFunc 类型,HandlerFunc 类型实现了 Handler 的 ServeHTTP 方法,底层可以同时使用各种类型来实现 Handler 接口进行处理。

可以思考一下,以下代码:

package main

import "net/http"

func (this *Refer) ServeHTTP(response http.ResponseWriter, req *http.Request) {
	if req.Referer() == this.refer {
		this.handler.ServeHTTP(response, req)
	} else {
		response.WriteHeader(403)
	}
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("this is handler"))
}

func hello(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("hello"))
}

func main() {
	referer := &Refer{
		handler: http.HandlerFunc(myHandler),
		refer:   "www.shirdon.com",
	}

	http.HandleFunc("/hello", hello)
	// handler
	http.ListenAndServe(":8080", referer)

}

type Refer struct {
	handler http.Handler
	refer   string
}

http.ListenAndServe:

HandlerFunc:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一彡十

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值