Skip to content

Golang 的接口型函数

Posted on:May 6, 2023 at 02:15 AM

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。


Golang 的接口型函数

demo

接口型函数的定义
// A Getter loads data for a key.
// 接口
type Getter interface {
	Get(key string) ([]byte, error)
}

// A GetterFunc implements Getter with a function.
// 接口型函数
type GetterFunc func(key string) ([]byte, error)

// Get implements Getter interface function
// 接口型函数实现的方法
func (f GetterFunc) Get(key string) ([]byte, error) {
	return f(key)
}
实现接口示例
func GetFromSource(getter Getter, key string) []byte {
	buf, err := getter.Get(key)
	if err == nil {
		return buf
	}
	return nil
}

注意,此时 getter.Get() 尚未实现,我们可以通过以下方法实现

GetFromSource(GetterFunc(func(key string) ([]byte, error) {
	return []byte(key), nil
}), "hello")
func test(key string) ([]byte, error) {
	return []byte(key), nil
}

func main() {
    GetFromSource(GetterFunc(test), "hello")
}
type MyGetter struct{}

func (g MyGetter) Get(key string) ([]byte, error) {
    // 实现获取数据的逻辑
    return []byte(key), nil
}

func main() {
    getter := MyGetter{}
    data := GetFromSource(getter, "hello")
    fmt.Println(string(data))
}
type Getter interface {
    Get(key string) ([]byte, error)
}

type MyGetter struct {
    Getter
}

func (g *MyGetter) Get(key string) ([]byte, error) {
    // 实现获取数据的逻辑
    return []byte(key), nil
}

func main() {
    getter := &MyGetter{}
    data := GetFromSource(getter, "hello")
    fmt.Println(string(data))
}

价值

使用场景

标准库 net/http/server.go 中
// 接口类型
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

// 接口型函数
type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
func Handle(pattern string, handler Handler)
func home(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	_, _ = w.Write([]byte("hello, index page"))
}

func main() {
	http.Handle("/home", http.HandlerFunc(home))
	_ = http.ListenAndServe("localhost:8000", nil)
}

func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func main() {
	http.HandleFunc("/home", home)
  /*
    ListenAndServer 的第二个接口也是接口类型
    传入 nil 为默认路由
    传入 实现好的[Handler接口] 就可以自定义路由
  */
	_ = http.ListenAndServe("localhost:8000", nil)
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	if handler == nil {
		panic("http: nil handler")
	}
	mux.Handle(pattern, HandlerFunc(handler))
}

package main

import (
	"log"
	"net/http"
)

type server int

func (h *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Println(r.URL.Path)
	w.Write([]byte("Hello World!"))
}

func main() {
	var s server
	http.ListenAndServe("localhost:9999", &s)
}
// 接口类型
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

// 接口型函数
type HandlerFunc func(ResponseWriter, *Request)

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

参考: