首先,这是本节的完整代码。
package main
import (
"fmt"
)
// インボーカーインターフェース
type Invoker interface {
// Callメソッドを実装する必要があります
Call(interface{})
}
// 構造体タイプ
type Struct struct {
}
// InvokerのCallを実装する
func (s *Struct) Call(p interface{}) {
fmt.Println("from struct", p)
}
// 関数を型として定義する
type FuncCaller func(interface{})
// InvokerのCallを実装する
func (f FuncCaller) Call(p interface{}) {
// f関数本体を呼び出す
f(p)
}
func main() {
// インターフェース変数を宣言する
var invoker Invoker
// 構造体インスタンスを作成する
s := new(Struct)
// インスタンス化された構造体をインターフェイスに割り当てる
invoker = s
// インターフェイスを使用してインスタンス化された構造体のメソッドStruct.Callを呼び出します
invoker.Call("hello")
// 無名関数をFuncCaller型に変換し、それをインターフェースに割り当てる
invoker = FuncCaller(func(v interface{}) {
fmt.Println("from function", v)
})
// インターフェースを使用してFuncCaller.Callを呼び出します。内部では、関数本体が呼び出されます。
invoker.Call("hello")
} 我有一个这样的界面:
type Invoker interface {
Call(interface{})
} 该接口必须实现 Call() 方法。调用时,会传递一个interface{}类型的变量。这种类型的变量代表任何类型的值。
接下来,使用结构体来实现接口。
结构体实现接口
实现Invoker接口的结构体代码如下:
// Structure Type
type Struct struct {
}
// Invokerの呼び出しを実装する
func (s *Struct) Call(p interface{}) {
fmt.Println("from struct", p)
} 代码说明如下:
- 第二行定义了一个结构体,但本例中的结构体不需要任何成员,主要演示如何实现 Invoker。
- 第 6 行的 Call() 是该结构的一个方法。该方法的作用是打印struct的值和传递的接口的类型。 {}
实例化定义的Struct类型并将其传递给接口进行调用。这是代码:
var invoker Invoker
s := new(Struct)
invoker = s
invoker.Call("こんにちは") 代码说明如下:
- 第 2 行声明了一个 Invoker 类型的变量。
- 第 5 行,使用 new 实例化结构。该行也可以写为 s:=&Struct。
- 第8行,对invoker的赋值成功,因为invoker的类型是*Struct,并且Invoker接口类型已经实现。
- 第11行,通过接口的Call()方法传递hello,此时Struct结构体的Call()方法被调用。
接下来我们就比较一下函数实现结构的差异。
这是代码输出:
from struct こんにちは
函数体实现接口
您不能直接在函数声明中实现接口。将函数定义为类型后,该类型将用于实现结构。当调用类型方法时,必须调用函数体。
// Function is defined as a type
type FuncCaller func(interface{})
// Implementation of Invoker's Call
func (f FuncCaller) Call(p interface{}) {
// Call the body of the f() function
f(p)
} 代码说明如下:
- 第二行将 func(interface{}) 定义为 FuncCaller 类型。
- 在第 5 行中,FuncCaller 的 Call() 方法实现了 Invoker 的 Call() 方法。
- 第8行,无论func(interface{})如何,都会调用FuncCaller的Call()方法,并且必须手动调用函数体。
上面的代码仅定义了函数的类型,必须由函数本身进行逻辑处理。无需实例化 FuncCaller。您只需将函数转换为 FuncCaller 类型即可。函数的源可以是命名函数、匿名函数或闭包。请参阅下面的代码。
// Declare interface variable
var invoker Invoker
// Convert anonymous function to FuncCaller type, and then assign it to the interface
invoker = FuncCaller(func(v interface{}) {
fmt.Println("from function", v)
})
// Use the interface to call FuncCaller.Call, which will invoke the underlying function
invoker.Call("hello") 代码说明如下:
- 第二行声明接口变量。
- 第 5 行将 func(v Interface{}){} 匿名函数转换为 FuncCaller 类型(只能转换函数签名)。在本例中,FuncCaller 类型实现了 Invoker 的 Call() 方法,并且对调用接口的赋值成功。
- 第 10 行使用接口方法调用。
这是代码输出:
from function hello

HTTP包中包含handler接口定义,代码如下:
type handler interface {
ServeHTTP(ResponseWriter, *Request)
} 处理程序用于定义每个 HTTP 请求和响应的处理。
同时,还可以使用处理函数来实现接口。这定义为:
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接口进行处理。




![2021 年如何设置 Raspberry Pi Web 服务器 [指南]](https://i0.wp.com/pcmanabu.com/wp-content/uploads/2019/10/web-server-02-309x198.png?w=1200&resize=1200,0&ssl=1)

